Skip to content

Commit 88dd90c

Browse files
committed
refactor: consolidate extraction safety, share yapdb tail, split megafiles
Safe extraction (security-sensitive consolidation): - new pkg/safepath: Join / JoinStrict / SymlinkTarget / EntrySymlinkTarget — ONE filepath.Rel-based containment implementation with an adversarial test suite (traversal, prefix-aliasing, "/" root clamping, symlink escapes) - the five hand-rolled copies (archive/tar.go, aptinstall/extract.go, dnfinstall/safepath.go, apkindex/install.go, container/rootless) are now thin delegators keeping their local names and tests - HARDENING: a member literally named "../etc/passwd" is now rejected even when root is "/" — filepath.Clean clamps ".." at the root, and the apt/dnf copies silently accepted the clamped form (apk already rejected it; rpm >= 4.18 and dpkg reject such names too) - HARDENING: container rootfs layer extraction (rootless pull) now validates symlink targets; previously a malicious layer could plant a symlink escaping the rootfs and write through it with a later entry - archive keeps its stricter any-".."-segment rejection for source archives on top of the shared containment Dedup: - yapdb.RecordInstalled: shared open/insert/close tail; the format-specific writeYapdb functions in aptinstall and dnfinstall now only assemble metadata - cmd/yap/command.ResolveFlexibleDistro: parse-args + auto-detect + userProvided tracking shared by build and zap File splits (mechanical, no behavior change): - pkg/aptcache: aptcache.go (1957 lines) → aptcache.go (cache+resolver, 576) + sources.go (449) + parse.go (605) + download.go (356) - pkg/pkgbuild: filterInstalled* family (253 lines) → filter_installed.go
1 parent 18cffdf commit 88dd90c

31 files changed

Lines changed: 2120 additions & 1887 deletions

.github/workflows/_reusable-docker-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ on:
1717
description: "Go version to use"
1818
required: false
1919
type: string
20-
default: "1.26.1"
20+
default: "1.26.4"
2121
push:
2222
description: "Push image to registry"
2323
required: false

.github/workflows/_reusable-go-setup.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
description: "Go version to use"
99
required: false
1010
type: string
11-
default: "1.26.1"
11+
default: "1.26.4"
1212
download-deps:
1313
description: "Download dependencies"
1414
required: false

.github/workflows/_reusable-security-scan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
description: "Go version to use"
99
required: false
1010
type: string
11-
default: "1.26.1"
11+
default: "1.26.4"
1212
upload-sarif:
1313
description: "Upload SARIF to GitHub Security"
1414
required: false

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ concurrency:
2020
cancel-in-progress: true
2121

2222
env:
23-
GO_VERSION: "1.26.1"
23+
GO_VERSION: "1.26.4"
2424

2525
jobs:
2626
# ===================================
@@ -75,7 +75,7 @@ jobs:
7575
name: 🔒 Security Scan
7676
uses: ./.github/workflows/_reusable-security-scan.yml
7777
with:
78-
go-version: "1.26.1"
78+
go-version: "1.26.4"
7979
upload-sarif: true
8080
run-vulncheck: false
8181

@@ -92,7 +92,7 @@ jobs:
9292
matrix:
9393
os: [ubuntu-latest]
9494
# os: [ubuntu-latest, macos-latest, windows-latest]
95-
go-version: ["1.26.1"]
95+
go-version: ["1.26.4"]
9696

9797
steps:
9898
- name: 📂 Checkout code

.github/workflows/coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ concurrency:
1919
cancel-in-progress: true
2020

2121
env:
22-
GO_VERSION: "1.26.1"
22+
GO_VERSION: "1.26.4"
2323

2424
jobs:
2525
# ===================================

.github/workflows/dependencies.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ concurrency:
2626
cancel-in-progress: true
2727

2828
env:
29-
GO_VERSION: "1.26.1"
29+
GO_VERSION: "1.26.4"
3030

3131
jobs:
3232
# ===================================

.github/workflows/docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ concurrency:
2020

2121
env:
2222
REGISTRY: ghcr.io
23-
GO_VERSION: "1.26.1"
23+
GO_VERSION: "1.26.4"
2424

2525
jobs:
2626
# Generate matrix for base OS builds

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ concurrency:
2121
cancel-in-progress: false
2222

2323
env:
24-
GO_VERSION: "1.26.1"
24+
GO_VERSION: "1.26.4"
2525
REGISTRY: ghcr.io
2626

2727
jobs:

.github/workflows/security.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ concurrency:
2121
cancel-in-progress: true
2222

2323
env:
24-
GO_VERSION: "1.26.1"
24+
GO_VERSION: "1.26.4"
2525

2626
jobs:
2727
# ===================================
@@ -31,7 +31,7 @@ jobs:
3131
name: 🔍 Static Analysis
3232
uses: ./.github/workflows/_reusable-security-scan.yml
3333
with:
34-
go-version: "1.26.1"
34+
go-version: "1.26.4"
3535
upload-sarif: true
3636
run-vulncheck: false
3737

@@ -42,7 +42,7 @@ jobs:
4242
name: 🛡️ Vulnerability Scan
4343
uses: ./.github/workflows/_reusable-security-scan.yml
4444
with:
45-
go-version: "1.26.1"
45+
go-version: "1.26.4"
4646
upload-sarif: false
4747
run-vulncheck: true
4848

AGENTS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
| `pkg/dnfinstall/` | RPM install (GPG verify → CPIO extract → scriptlets → yapdb) |
3030
| `pkg/yapdb/` | YAP-internal SQLite state DB for installed packages (cross-format) |
3131
| `pkg/httpclient/` | Shared HTTP client: timeouts, size caps, transient-failure retry with backoff |
32+
| `pkg/safepath/` | Canonical zip-slip / symlink-escape containment checks for all extractors |
3233
| `pkg/signing/` | APK RSA + DEB/RPM/Pacman GPG signing |
3334
| `pkg/sbom/` | CycloneDX 1.5 + SPDX 2.3 generation |
3435
| `pkg/color/` | Zero-dependency ANSI color helpers |
@@ -259,6 +260,7 @@ Test script: `scripts/e2e-rpm.sh` (runs inside Rocky 8 container)
259260
- Mirror failover (dnf) — `pkg/dnfcache` keeps every `baseurl=` entry (incl. dnf-style continuation lines) and up to 5 mirrorlist/metalink mirrors; repomd + primary always come from the SAME mirror (no mixed metadata generations); dead (4xx/network) or stale (checksum-mismatch) mirrors are skipped with a warn; the winning mirror is persisted in `.baseurl` and preferred for package downloads
260261
- Transient-failure retry — `pkg/httpclient` `WithRetry`/`IsRetryable` (3 attempts, exponential backoff + jitter; retries transport errors, mid-body EOF, HTTP 408/429/5xx; never other 4xx/size-cap/ctx-cancel); wired into all dnf/apt/apk/pacman metadata and package fetch paths; tests shrink backoff via `httpclient.SetRetryPolicy` in `TestMain`
261262
- Source download retry (gensum / pkg/source / pkg/platform) — `pkg/download` (grab-based, resume-capable) classifies retryability with typed checks: `grab.StatusCodeError` 408/429/5xx retried, other 4xx definitive, `grab.ErrBadLength` retried after clearing the unresumable partial, ctx-cancel never retried, transport errors defer to `httpclient.IsRetryable`; backoff is `backoffBase` (1s, doubles; tests shrink it in `TestMain`)
263+
- Extraction safety — `pkg/safepath` (`Join`, `JoinStrict`, `SymlinkTarget`, `EntrySymlinkTarget`): one Rel-based containment implementation shared by archive, aptinstall, dnfinstall, apkindex, and container/rootless (per-package wrappers keep local names); hostile `..`-bearing member names are rejected even under root "/" (Clean clamping is NOT trusted), and rootfs layer extraction validates symlink targets
262264
- Transitive cross-build dep extraction — `pkg/builders/common/cross.go` `DownloadClosure`
263265
- Package signing — APK RSA + DEB/RPM/Pacman GPG
264266
- SBOM — CycloneDX 1.5 + SPDX 2.3

0 commit comments

Comments
 (0)