Skip to content

fix(deployment/solutils): validate archive paths to prevent Zip Slip#22405

Open
ozpool wants to merge 1 commit into
smartcontractkit:developfrom
ozpool:fix/21003-zipslip-artifacts
Open

fix(deployment/solutils): validate archive paths to prevent Zip Slip#22405
ozpool wants to merge 1 commit into
smartcontractkit:developfrom
ozpool:fix/21003-zipslip-artifacts

Conversation

@ozpool
Copy link
Copy Markdown

@ozpool ozpool commented May 12, 2026

Summary

  • Fixes [BUG] Validate extraction paths in downloadProgramArtifacts to prevent path traversal #21003. downloadProgramArtifacts in deployment/utils/solutils/artifacts.go previously relied solely on filepath.Base when extracting tar entries. filepath.Base silently flattens path-traversal entries like ../../etc/passwd to passwd instead of rejecting them, which can mask malicious archives and cause silent filename collisions.
  • Reject any tar entry whose name is not local (filepath.IsLocal returns false for empty paths, absolute paths, and any path that traverses outside the target via ..).
  • Defense-in-depth: verify with filepath.Rel that the cleaned output path is contained within the cleaned targetDir before writing.
  • Added TestDownloadProgramArtifacts_RejectsZipSlipEntries covering parent traversal, nested traversal, absolute paths, and empty entry names. Confirms no file is written inside or outside the target directory when a malicious archive is served.

Test plan

  • go test ./utils/solutils/... -count=1 from deployment/ — all tests pass including the new Zip Slip cases and existing extraction/cancellation/URL/non-existent-dir tests.
  • go vet ./utils/solutils/... — clean.
  • gofmt -l deployment/utils/solutils/ — clean.

downloadProgramArtifacts extracted tar entries using only filepath.Base,
which silently flattens path-traversal entries (e.g. "../../etc/passwd")
into the target directory rather than rejecting them. While Base prevents
the worst case of writing outside targetDir, it can still cause silent
filename collisions when a malicious archive ships crafted entries.

Reject any tar entry whose name is not local via filepath.IsLocal
(empty, absolute, or containing ".."), and additionally verify with
filepath.Rel that the resolved output path is contained within the
cleaned targetDir as defense-in-depth.

Closes smartcontractkit#21003
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Validate extraction paths in downloadProgramArtifacts to prevent path traversal

1 participant