Skip to content

feat(archiver): validate deployment archives before extraction - #1619

Closed
Soner (shyim) wants to merge 4 commits into
mainfrom
feat/archive-validation
Closed

Soner (shyim) wants to merge 4 commits into
mainfrom
feat/archive-validation

Conversation

@shyim

@shyim Soner (shyim) commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

What changed?

Added tar.gz validation for paths, entry types, permissions, symlinks and gzip integrity, with tests.

Why?

Archive validation for deployment epic. No there is no proper go lib out who would handle this

How was this tested?

unit tests

Related issue or discussion

Split from #1573.

Summary by CodeRabbit

  • New Features
    • Compressed tar archives can now be validated without extracting them. Validation rejects unsafe or duplicate paths, unsupported entries, invalid symlinks, and archives with corrupted or incomplete compression data. Regular files, directories, relative symlinks, and global metadata headers are accepted when valid. The check also observes cancellation requests and detects symlink paths that escape the archive or traverse non-directory entries.

@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: d127f266-1cd4-46b2-98e3-2af191bef1f4

📥 Commits

Reviewing files that changed from the base of the PR and between 8644c89 and 682a748.

📒 Files selected for processing (3)
  • internal/archiver/tar_validate.go
  • internal/archiver/tar_validate_test.go
  • internal/extension/create_test.go
💤 Files with no reviewable changes (1)
  • internal/extension/create_test.go

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.


📝 Walkthrough

Walkthrough

Adds ValidateTarGz to check gzip-compressed tar archives without extracting them. The validator checks archive paths, entry types, permissions, symlinks, gzip integrity, and context cancellation.

Changes

Tar archive validation

Layer / File(s) Summary
Archive entry and path validation
internal/archiver/tar_validate.go
ValidateTarGz checks archive entries, paths, permissions, and symlink resolution. It consumes the gzip stream and joins any close error with the validation result.
Validator test coverage
internal/archiver/tar_validate_test.go
Tests cover accepted and rejected entries, gzip checksum and truncation errors, context cancellation, and an archive with a symlink target under excluded node_modules.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to 682a7

No actionable merge-blocking issue remains; the archive validation change is ready for normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 682a7

The validator adds checks for unsafe archives, but it is not yet connected to a deployment extraction path shown in this revision. No new runtime exposure is established; protection at extraction remains unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — No production caller of the new validator was established in the inspected paths, so its effective attacker-controlled reachability, privileges, and deployment blast radius cannot be determined. The inspected cache extraction path consumes downloaded bytes without calling it and is not changed by this PR.

Security Findings and Attack Paths

  • inferred — No path-traversal attack through this PR is verified. The candidate concerning global PAX handling remains deferred because the deployment extractor and its interpretation of those records are unavailable.

Trust Boundaries and Controls

  • observed — The validator checks parsed archive metadata, but its error-only, consuming interface does not itself bind a successful check to the bytes subsequently extracted.

Resilience and Maintainability Implications

  • inferred — If the validator is later used as an extraction gate, independently maintained validation and extraction policies could drift. The inspected cache extractor already handles archive paths and symlinks separately; this PR does not establish it as a validator consumer.

Hardening Proposals

  • proposed — Before relying on this validator for deployment protection, establish the extraction handoff on the same archive bytes and verify global PAX path and link-path behavior against the actual extractor.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description covers what changed, why the change was made, testing, and the related issue. The testing section is brief but sufficient for a mostly complete description.
Title check ✅ Passed The title clearly and concisely describes the main change: validating deployment archives before extraction.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

Codecov Comments Bot (codecov-commenter) commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.52941% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 65.18%. Comparing base (8644c89) to head (682a748).

Files with missing lines Patch % Lines
internal/archiver/tar_validate.go 98.52% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1619      +/-   ##
==========================================
+ Coverage   65.11%   65.18%   +0.07%     
==========================================
  Files         479      480       +1     
  Lines       31643    31711      +68     
==========================================
+ Hits        20604    20672      +68     
  Misses      11039    11039              
Flag Coverage Δ
go-test 65.18% <98.52%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Soner (shyim) and others added 2 commits September 28, 2026 09:34
Skip PAX global headers, which git archive emits as metadata. Allow
symlinks whose targets are absent from the archive (e.g. excluded by
WriteTarGz) as long as they stay inside the archive root.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shyim
Soner (shyim) marked this pull request as ready for review September 28, 2026 08:15
Comment on lines +14 to +18
// ValidateTarGz checks an archive before extracting it on a deployment host.
// Only regular files, directories, and relative symlinks that stay inside the
// archive root are allowed. Symlink targets may be missing, e.g. excluded paths.
// It consumes the gzip stream, including its checksum, without extracting files.
func ValidateTarGz(ctx context.Context, r io.Reader) (err error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Archive validation for deployment epic. No there is no proper go lib out who would handle this

Is there really a need for this? E.g. where are these broken archives coming from in the first place? And wouldn't it be enough to just error while extracting (e.g. following "parse, don't validate" principle).

I'm trying to understand the background and underlying issue we want to solve here. Another idea could also be that we somehow "sign" or "checksum" the archives we generated and only accept those to make sure nobody messed with them 🤔

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valid 🤔 lets keep it out for simplicity 🤔

@shyim
Soner (shyim) deleted the feat/archive-validation branch September 29, 2026 06:54
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.

3 participants