Skip to content

Fix path traversal (Wpress Slip) in .wpress extractor#3142

Merged
wojtekn merged 4 commits intotrunkfrom
fix-wpress-path-traversal
Apr 20, 2026
Merged

Fix path traversal (Wpress Slip) in .wpress extractor#3142
wojtekn merged 4 commits intotrunkfrom
fix-wpress-path-traversal

Conversation

@wojtekn
Copy link
Copy Markdown
Contributor

@wojtekn wojtekn commented Apr 20, 2026

Related issues

Reported via HackerOne (path traversal / Wpress Slip in BackupHandlerWpress).

Proposed Changes

readBlockToFile joined header.prefix and header.name from the archive directly into the output path with no bounds check. A crafted .wpress file with prefix=".." 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() using path.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.ts
  • apps/cli/lib/import-export/import/handlers/backup-handler-wpress.ts

The .zip and .tar.gz handlers are not affected (they delegate to yauzl / tar which handle this at the library level).

Testing Instructions

  • Craft a .wpress with prefix=".." (30-line Python script from the report). Import via Studio → verify no file appears outside the extraction directory.
  • Import a legitimate .wpress backup → verify it extracts correctly and the import completes successfully.
  • Confirm no regressions in normal import flow for .zip and .tar.gz formats.

Pre-merge Checklist

  • Linter passes on modified files
  • TypeScript typecheck passes for apps/studio and apps/cli
  • CI passes

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.
@wojtekn wojtekn self-assigned this Apr 20, 2026
@wpmobilebot
Copy link
Copy Markdown
Collaborator

wpmobilebot commented Apr 20, 2026

📊 Performance Test Results

Comparing 1a8203a vs trunk

app-size

Metric trunk 1a8203a Diff Change
App Size (Mac) 1439.62 MB 1439.61 MB 0.01 MB ⚪ 0.0%

site-editor

Metric trunk 1a8203a Diff Change
load 1875 ms 1895 ms +20 ms ⚪ 0.0%

site-startup

Metric trunk 1a8203a Diff Change
siteCreation 8124 ms 8131 ms +7 ms ⚪ 0.0%
siteStartup 4944 ms 4948 ms +4 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

wojtekn added 2 commits April 20, 2026 12:04
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.
@wojtekn
Copy link
Copy Markdown
Contributor Author

wojtekn commented Apr 20, 2026

I tested the issue using a minimal crafted poc.wpress file (https://cldup.com/RwIwLLTcjs.wpress). With Studio 1.7.8, I see the file after the import:

% find /var/folders -name "traversal-marker.txt" 2>/dev/null
/var/folders/6x/h7nh9c9d5fg_jxtx7bc053240000gr/T/traversal-marker.txt

With this PR, the file doesn't appear in the mentioned path.

@wojtekn wojtekn changed the title security: fix path traversal (Wpress Slip) in .wpress extractor Fix path traversal (Wpress Slip) in .wpress extractor Apr 20, 2026
@wojtekn wojtekn requested a review from a team April 20, 2026 10:25
Copy link
Copy Markdown
Contributor

@katinthehatsite katinthehatsite left a comment

Choose a reason for hiding this comment

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

The change worked as expected for me, and the malicious file was identified and caught correctly 👍

@wojtekn wojtekn merged commit 685dce2 into trunk Apr 20, 2026
10 checks passed
@wojtekn wojtekn deleted the fix-wpress-path-traversal branch April 20, 2026 14:27
Copy link
Copy Markdown
Member

@sejas sejas left a comment

Choose a reason for hiding this comment

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

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.

@wojtekn
Copy link
Copy Markdown
Contributor Author

wojtekn commented Apr 21, 2026

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.

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