Skip to content

fix: reject zip-slip / path-traversal entries in extractTarball#22

Merged
heznpc merged 1 commit intomainfrom
fix/tar-zip-slip-filter
May 2, 2026
Merged

fix: reject zip-slip / path-traversal entries in extractTarball#22
heznpc merged 1 commit intomainfrom
fix/tar-zip-slip-filter

Conversation

@heznpc
Copy link
Copy Markdown
Member

@heznpc heznpc commented May 2, 2026

From the 2026-05-01 audit (P1.4):

tar.extract({ strip: 1 }) had no filter — a hostile or corrupt tarball entry like ../../etc/passwd would extract outside the destination directory.

Fix

  • Added isSafeTarEntry() predicate (exported) that rejects empty, absolute (POSIX), Windows drive-letter, and ..-escape paths.
  • filter callback in extractTarball consults the predicate.
  • First rejected entry is surfaced via new DownloadError code UNSAFE_ENTRY.
  • Test coverage: ~12 new assertions across safe/unsafe cases + a regression test for mid-path .. that collapses back inside cwd.

Test plan

  • Local: 52 tests passing (+12 new)
  • CI green

`tar.extract({ strip: 1 })` on an attacker-controlled tarball will happily
write `../../etc/passwd` if the entry path escapes cwd after the strip.
Add an explicit `filter` predicate that rejects:
- empty paths
- absolute paths (POSIX leading `/`)
- Windows drive-letter paths ("C:foo", "C:\\…")
- entries that normalize to something starting with `..` (escapes cwd)

The first rejected entry is captured and surfaced as a `DownloadError`
with a new `UNSAFE_ENTRY` code, instead of `filter` silently skipping it.

Tests: `isSafeTarEntry` is now exported and covered with safe + unsafe
cases including a regression check that mid-path `..` segments which
collapse back inside cwd are still accepted.
@heznpc heznpc merged commit dca1882 into main May 2, 2026
1 check passed
@heznpc heznpc deleted the fix/tar-zip-slip-filter branch May 2, 2026 01:27
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.

1 participant