fix: sanitize download filenames to prevent path traversal (CWE-22)#8718
fix: sanitize download filenames to prevent path traversal (CWE-22)#8718DevZenPro wants to merge 3 commits into
Conversation
Fixes openclaw#8696 The buildTempDownloadPath function used the remote server's suggested filename directly without sanitization, allowing a malicious site to write files outside /tmp/openclaw/downloads via path traversal sequences in Content-Disposition headers. Changes: - Add sanitizeDownloadFilename() that normalizes separators, strips directory components via path.basename(), removes traversal patterns and null bytes, with a fallback to 'download.bin' - Add belt-and-suspenders resolved path check in buildTempDownloadPath() to ensure the output stays within the downloads directory - Add comprehensive test suite covering traversal sequences, mixed separators, null bytes, edge cases, and normal filenames refactor: address review feedback on path traversal fix - Replace brittle startsWith() prefix check with path.relative() via isWithinDir() helper — robust across case-insensitive filesystems - Remove aggressive '..' stripping from sanitizeDownloadFilename() that mangled legitimate filenames like 'my..notes.txt' — path.basename() already handles directory traversal; only reject exact '.' and '..' - Add test for single dot basename and legitimate double-dot filenames fix: use replaceAll for null byte removal to satisfy no-control-regex lint
7cf5ef6 to
1727dc7
Compare
CI StatusAll checks introduced or affected by this PR are passing ✅:
The only failing check is tsgo with: This is a pre-existing issue in an unrelated file ( |
bfc1ccb to
f92900f
Compare
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing as AI-assisted stale-fix triage. Linked issue #8696 ("[Bug]: Playwright download suggested filename allows path traversal writes") is currently closed and was closed on 2026-02-24T04:23:12Z with state reason not_planned. If the underlying bug is still reproducible on current main, please reopen this PR (or open a new focused fix PR) and reference both #8696 and #8718 for fast re-triage. |
Summary
Fixes #8696
The
buildTempDownloadPathfunction constructs an output path directly from the remote server's suggested filename without sanitization. A malicious site can set aContent-Dispositionfilename containing path traversal sequences (e.g.,../../../etc/passwd) to write the downloaded file outside/tmp/openclaw/downloads, enabling arbitrary file overwrite.Changes
src/browser/pw-tools-core.downloads.tsAdded
sanitizeDownloadFilename()— a dedicated sanitization function that:path.basename()..traversal patterns and null bytesdownload.binif the result is empty or only dotsAdded resolved path guard in
buildTempDownloadPath()— belt-and-suspenders check usingpath.resolve()+startsWith()to ensure the final path stays within the downloads directory, even if future edge cases bypass the filename sanitizersrc/browser/pw-tools-core.sanitize-download-filename.test.ts(new)../../../etc/passwd)..\\..\\..\\windows\\system32\\config)Testing
All new tests pass. All existing download tests continue to pass (verified with
pnpm vitest run).Security Impact
Closes a CVSS 8.8 (High) path traversal vulnerability that could allow arbitrary file overwrites on the host when the browser automation API processes downloads from malicious sites.
Greptile Overview
Greptile Summary
This PR hardens Playwright download handling by introducing
sanitizeDownloadFilename()and using it inbuildTempDownloadPath()so that server-suggested filenames can’t inject path separators / traversal sequences into the temporary download path. It also adds a “resolved path must remain within downloads dir” guard, plus a dedicated Vitest suite covering common traversal, separator, and empty/null-byte cases.The change fits into the browser tooling layer (
pw-tools-core.*) wherewaitForDownloadViaPlaywright()derives an output path fromdownload.suggestedFilename()and persists the file viadownload.saveAs(); sanitizing at path construction time prevents a maliciousContent-Dispositionfilename from escaping the intended downloads directory.Confidence Score: 4/5
startsWith-based directory containment check across filesystem/path normalization behaviors, plus potentially over-aggressive removal of..sequences inside otherwise-benign basenames.(2/5) Greptile learns from your feedback when you react with thumbs up/down!