Skip to content

fix(security): prevent Zip Slip path traversal in harUnzip#40623

Open
SebTardif wants to merge 1 commit intomicrosoft:mainfrom
SebTardif:fix/zip-slip-harunzip
Open

fix(security): prevent Zip Slip path traversal in harUnzip#40623
SebTardif wants to merge 1 commit intomicrosoft:mainfrom
SebTardif:fix/zip-slip-harunzip

Conversation

@SebTardif
Copy link
Copy Markdown

Summary

Fixes #40622

The harUnzip() function in packages/playwright-core/src/server/localUtils.ts extracts zip entries using path.join(resourcesDir, entry) without validating that the resolved path stays inside resourcesDir. A crafted .har.zip file with entries containing path traversal sequences (e.g. ../../etc/cron.d/evil) could write files to arbitrary locations on the filesystem.

Fix

Added resolveWithinRoot() validation before writing each extracted zip entry, rejecting any entry whose resolved path escapes the target resourcesDir. This follows the exact same pattern already used in extractTrace() in packages/playwright-core/src/tools/trace/traceParser.ts:

const outPath = resolveWithinRoot(resourcesDir, entry);
if (!outPath)
  throw new Error(`HAR zip entry '${entry}' escapes output directory`);
await progress.race(fs.promises.writeFile(outPath, buffer));

Changes

  • packages/playwright-core/src/server/localUtils.ts: Import resolveWithinRoot from @utils/fileUtils and add path containment check in harUnzip().

Test plan

The resolveWithinRoot() utility is already thoroughly tested via the existing extractTrace() codepath. The fix is a 3-line addition that rejects any zip entry with a relative path escaping the output directory (returns null for absolute paths and paths that resolve outside the root after normalization).

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@SebTardif SebTardif force-pushed the fix/zip-slip-harunzip branch from fbad648 to 74cee1d Compare May 5, 2026 08:51
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Add resolveWithinRoot() validation to harUnzip() to ensure zip entry
paths cannot escape the target resourcesDir via path traversal sequences
(e.g. ../../etc/evil). This follows the same pattern already used in
extractTrace() in traceParser.ts.

Fixes microsoft#40622
@SebTardif SebTardif force-pushed the fix/zip-slip-harunzip branch from 74cee1d to 7b86f65 Compare May 5, 2026 22:16
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Test results for "MCP"

2 failed
❌ [msedge] › mcp/dashboard.spec.ts:185 › should start dashboard and annotate when no dashboard is running @mcp-windows-latest-msedge
❌ [webkit] › mcp/config.ini.spec.ts:57 › ini config sets browser launch options @mcp-windows-latest-webkit

6941 passed, 1052 skipped


Merge workflow run.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Test results for "tests 1"

41655 passed, 851 skipped


Merge workflow run.

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.

Security: Zip Slip path traversal in harUnzip allows arbitrary file write

2 participants