Fix path traversal (Wpress Slip) in .wpress extractor#3142
Conversation
header.prefix and header.name were joined directly into the output path without bounds checking, allowing a crafted .wpress file to write files outside the extraction directory. Add isPathWithinDirectory() and check it before extracting each entry; traversal entries are skipped (data bytes consumed to keep cursor alignment) rather than aborting the import. Affects both the desktop main-process handler and the bundled CLI handler.
📊 Performance Test ResultsComparing 1a8203a vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
listFiles was returning raw '../...' paths into the file list, which flowed into validators and parseBackupContents where they'd be joined against the extraction directory again. Filter any entry whose joined path contains '..' components before adding to the list.
|
I tested the issue using a minimal crafted With this PR, the file doesn't appear in the mentioned path. |
katinthehatsite
left a comment
There was a problem hiding this comment.
The change worked as expected for me, and the malicious file was identified and caught correctly 👍
sejas
left a comment
There was a problem hiding this comment.
Thanks for the quick PR. I see we have /backup-handler-wpress.ts duplicated in CLI and Studio apps. So it makes sense to apply the fix in both parts.
Yes, I did that as a part of this PR. |
Related issues
Reported via HackerOne (path traversal / Wpress Slip in
BackupHandlerWpress).Proposed Changes
readBlockToFilejoinedheader.prefixandheader.namefrom the archive directly into the output path with no bounds check. A crafted.wpressfile withprefix=".."could write files outside the extraction directory — anywhere the Studio user has write access (shell config, SSH keys, launch agents, etc.).This is analogous to the Zip Slip class of vulnerabilities.
Fix: Add
isPathWithinDirectory()usingpath.resolve()to check that the resolved output path stays within the extraction directory before writing. Traversal entries are silently skipped; their data bytes are consumed so the file cursor stays aligned for subsequent entries.Both affected files patched identically:
apps/studio/src/lib/import-export/import/handlers/backup-handler-wpress.tsapps/cli/lib/import-export/import/handlers/backup-handler-wpress.tsThe
.zipand.tar.gzhandlers are not affected (they delegate toyauzl/tarwhich handle this at the library level).Testing Instructions
.wpresswithprefix=".."(30-line Python script from the report). Import via Studio → verify no file appears outside the extraction directory..wpressbackup → verify it extracts correctly and the import completes successfully..zipand.tar.gzformats.Pre-merge Checklist
apps/studioandapps/cli