Media: sanitize Content-Disposition filenames from remote fetches#27818
Media: sanitize Content-Disposition filenames from remote fetches#27818afurm wants to merge 10 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 521f3e4281
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Greptile SummaryAdds filename sanitization to prevent Windows-style path traversal in
Confidence Score: 5/5
Last reviewed commit: 521f3e4 |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47c9f247cd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aa9f075748
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (char === "/") { | ||
| segment = ""; | ||
| continue; |
There was a problem hiding this comment.
Preserve last segment when value ends with a separator
The new basename helper clears segment whenever it sees /, so inputs ending in a slash now sanitize to an empty string (for example filename="foo/bar/" or filename*=...foo%2Fbar%2F). Before this commit, path.basename returned bar, so this is a regression that can silently discard the server-provided filename and force fallback naming in fetchRemoteMedia.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2dca557b79
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cb03c0f298
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (next !== '"' && next !== "'") { | ||
| segment = ""; | ||
| continue; |
There was a problem hiding this comment.
Preserve multiple escaped backslashes before quotes
basenameWithWindowsSeparatorHeuristic only keeps a backslash when the immediate next character is a quote, so after unescapeHttpQuotedPair a decoded sequence like \\\" (two literal backslashes before a quote) is mishandled: the first backslash is treated as a separator and clears the accumulated basename. In a valid quoted-string filename that contains two backslashes before a quote, this truncates the filename stem (e.g. foo is dropped and only \"bar.txt remains), which is a behavioral regression for compliant Content-Disposition values.
Useful? React with 👍 / 👎.
|
This pull request has been automatically marked as stale due to inactivity. |
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing due to inactivity. |
Summary
Describe the problem and fix in 2–5 bullets:
fetchRemoteMediaparsedContent-Dispositionfilenames withpath.basename(), which does not treat Windows\separators as path separators on POSIX hosts...\\..\\secret.pdf, and traversal-like segments can propagate into downstream attachment metadata/labels instead of being reduced to a safe basename.Content-Dispositionparsing that normalizes\to/, strips control characters, and then takes a basename; applied to bothfilename=and RFC5987filename*=paths; added regression tests.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
Content-Dispositionfilenames that use Windows-style traversal separators (for example..\\..\\file.pdfbecomesfile.pdf).Security Impact (required)
Yes/No)NoYes/No)NoYes/No)NoYes/No)NoYes/No)NoYes, explain risk + mitigation: N/ARepro + Verification
Environment
Steps
fetchRemoteMedia()to receiveContent-Disposition: attachment; filename="..\\..\\secret.pdf".fetchRemoteMedia()and inspectresult.fileName.filename*=UTF-8''..%5C..%5Creport-final.pdf.Expected
secret.pdf/report-final.pdf), without traversal-like segments.Actual
path.basename()preserved backslash-delimited segments, so..\\..\\secret.pdfcould survive as-is.Evidence
Attach at least one:
Test snippet (after patch):
pnpm test src/media/fetch.test.ts→✓ src/media/fetch.test.ts (5 tests)Human Verification (required)
What you personally verified (not just CI), and how:
/Users/afurm/Development/openclaw/src/media/fetch.test.ts; confirmed new cases pass for bothfilename=andfilename*=handling.filename*.Compatibility / Migration
Yes/No)YesYes/No)NoYes/No)NoFailure Recovery (if this breaks)
521f3e428(or restore the two touched files and redeploy)./Users/afurm/Development/openclaw/src/media/fetch.ts,/Users/afurm/Development/openclaw/src/media/fetch.test.tsRisks and Mitigations
List only real risks for this PR. Add/remove entries as needed. If none, write
None.Content-Dispositionfilename parsing only; network behavior and storage paths are unchanged, and regression tests cover both standard and RFC5987 header formats.