fix(files): escape user filenames in the Content-Disposition header - #6430
Conversation
The download name is the user's originalName, which only rejects path separators, so a quote reached the quoted filename parameter unescaped and could close it and append parameters of its own. An injected filename* is the one that matters: RFC 6266 tells clients to prefer it, so it decides the name the file lands under on disk regardless of what the UI showed. - neutralize the quote, backslash and non-printable characters in the quoted parameter, and neutralize the semicolon there too since that fallback exists for clients liable to split parameters without honouring the quoting - percent-encode the filename* ext-value fully, including the characters encodeURIComponent leaves raw — the apostrophe is the ext-value delimiter - names that are already safe printable ASCII keep their exact previous header Also stops a control character in a name from producing an invalid header value, which previously made the download 500.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview The quoted Control characters in a name no longer produce invalid header values that could fail the response. Unit tests cover injection via quotes/ Reviewed by Cursor Bugbot for commit bbeee90. Configure here. |
Greptile SummaryThe PR hardens file-download
Confidence Score: 5/5The PR appears safe to merge with no actionable defects identified. The revised encoding safely neutralizes quoted-parameter injection, emits valid percent-encoded extended values, and preserves the previous header for ordinary safe filenames.
|
| Filename | Overview |
|---|---|
| apps/sim/app/api/files/utils.ts | Safely constructs quoted and extended filename parameters without exposing a concrete regression. |
| apps/sim/app/api/files/utils.test.ts | Adds focused regression tests covering unsafe, Unicode, control-character, and ordinary filename behavior. |
Reviews (1): Last reviewed commit: "fix(files): escape user filenames in the..." | Re-trigger Greptile
Summary
filenameparameter, so it cannot terminate the parameter or append parameters of its ownfilename*ext-value fully, including the charactersencodeURIComponentleaves rawType of Change
Testing
Added unit tests covering each case, including that an ordinary filename is byte-identical to before.
app/api/filessuite passes (247 tests); type-check and lint clean.Checklist