Harden artifact extraction symlink checks #7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/2-safe-extract"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why:
Changes:
Testing:
APPROVE
Verified the extraction validator against the full threat model. All four classes are rejected before a single byte is written (validation walks the headers, then
tar -xfruns only if clean), and normal extraction is preserved. Ran the suite locally: 28/28 green.../traversal —validateEntryresolvesnameagainstdestRealand rejects anything failingisInside(artifact-tar.js:237-238). Covered bytests/artifact-tar.test.js:75.path.isAbsolute(name)rejected at:236; absolute link targets rejected at:249. Covered by:88.isInsideat:250-252(:96).existingPathStaysInside(:205-227) walks each path component,lstats it, and if a component is a symlink whoserealpathSynclands outsidedestReal, refuses the archive. It is applied to every entry's own path (:239, so it catches a plain file written through a plantedlinked -> /outsidedir) and to link targets (:253).realpathSyncfully resolves chains, so nested/indirect symlinks are caught too. Covered by:103(file through escaping symlink) and:113(hardlink through escaping symlink).3/4), fifo (6), and any unknown typeflag fall through to theelseand are refused (:257-259). Fifo covered by:124.Also correct:
--no-same-owneron extract (:369) drops archive uid/gid restoration, which matters on a root runner. Fail-closed behavior is sound: nothing is written on any rejection (the no-partial-write assertions at:84-85etc. confirm it). Normal extraction unaffected, sinceexistingPathStaysInsideshort-circuits onENOENTfor a fresh/empty dest (:215); the happy-path tests at:58and:130pass.Non-blocking nits (not gating):
fs.realpathSync(cur)(:219) sits outside thetry/catchthat mapsENOENT(which only wraps thelstatSyncat:213). A dangling escaping symlink would surface a rawENOENTinstead ofUnsafeArchiveError. Still fails closed (extraction aborts, nothing written), so it is cosmetic, but wrapping it would keep the error type consistent.6) has a dedicated special-file test; device types3/4hit the identical branch but aren't asserted directly. Optional to add.tar -xfdesign retains an inherent TOCTOU window (an attacker with concurrent write access todestduring extraction); out of scope here, and this PR narrows it by rejecting symlinks already present at validation time.Clean approve. Not merging - over to you.