Skip to content

Replace extract-zip with secure yauzl-based extraction - #472

Draft
brondani wants to merge 7 commits into
mainfrom
replace-extract-zip-secure
Draft

Replace extract-zip with secure yauzl-based extraction#472
brondani wants to merge 7 commits into
mainfrom
replace-extract-zip-secure

Conversation

@brondani

@brondani brondani commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Fixes

  • Remove direct dependency on extract-zip
  • Enforce safe extraction by rejecting path traversal and symbolic-link ZIP entries while validating destination paths.
  • Preserve safe replacement of regular destination files using temporary files.

Changes

  • Replaced extract-zip with an in-repo yauzl-based ZIP extractor.
  • Updated project archive extraction call sites to use the new utility.
  • Added tests for regular extraction and archive path-safety handling.
  • Added yauzl dependencies, TypeScript types, and third-party license records.
  • Limit ZIP extraction resource usage (ZIP-bomb protections)

Checklist

  • 🤖 This change is covered by unit tests (if applicable).
  • 🤹 Manual testing has been performed.
  • 🛡️ Security impacts have been considered (if relevant).
  • 📖 Documentation updates are complete (if required).
  • 🧠 Third-party dependencies and TPIP updated (if required).

Reject archive entries that escape the destination or use unsafe symbolic
links and parent paths. Preserve safe overwrite behavior and add extraction
tests, dependency updates, and license records.
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ✅ 0 package(s) with unknown licenses.
  • ⚠️ 1 packages with OpenSSF Scorecard issues.
See the Details below.

OpenSSF Scorecard

PackageVersionScoreDetails
npm/pend 1.2.0 ⚠️ 2
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ -1No tokens found
SAST⚠️ 0no SAST tool detected
Pinned-Dependencies⚠️ -1no dependencies found
Dangerous-Workflow⚠️ -1no workflows found
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review⚠️ 0Found 0/13 approved changesets -- score normalized to 0
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
npm/yauzl 3.4.0 🟢 3.7
Details
CheckScoreReason
Maintained🟢 96 commit(s) and 5 issue activity found in the last 90 days -- score normalized to 9
Code-Review⚠️ 0Found 0/26 approved changesets -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@types/yauzl ^2.10.3 UnknownUnknown

Scanned Files

  • package-lock.json
  • package.json

@qltysh

qltysh Bot commented Aug 19, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

⬆️ Merging this pull request will increase total coverage on main by 0.1%.

Modified Files with Diff Coverage (2)

RatingFile% DiffUncovered Line #s
Coverage rating: F Coverage rating: F
src/data-manager/draft-project-data.ts33.3%110-215
New file Coverage rating: A
src/utils/extract-zip.ts95.7%87, 99, 118, 168, 206
Total94.1%
🤖 Increase coverage with AI coding...
In the `replace-extract-zip-secure` branch, add test coverage for this new code:

- `src/data-manager/draft-project-data.ts` -- Line 110-215
- `src/utils/extract-zip.ts` -- Lines 87, 99, 118, 168, and 206

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@brondani
brondani marked this pull request as ready for review August 20, 2026 06:55
soumeh01
soumeh01 previously approved these changes Aug 20, 2026

@soumeh01 soumeh01 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@jreineckearm

Copy link
Copy Markdown

@brondani , are there plans to move a variant of this to vsce-helper?

@brondani

Copy link
Copy Markdown
Collaborator Author

are there plans to move a variant of this to vsce-helper?

AFAIK this is not yet formally planned.
Would you prefer to drop this change and extend vsce-helper instead?

@jreineckearm

Copy link
Copy Markdown

If we extend vsce-helper, then we would get the goodness of this PR also for our CI downloads + unzip (and hence for other dependents of that). I believe it could still be used through the package in the production code here.

@brondani
brondani marked this pull request as draft August 24, 2026 08:54
Implemented ZIP-bomb protections in extract-zip.ts:
- Maximum 10,000 archive entries
- Maximum 512 MiB per extracted file
- Maximum 2 GiB aggregate uncompressed output
- Byte limits enforced by a streaming Transform before data reaches disk
- Correct yauzl cancellation using unpipe then destroy
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.

4 participants