fix: report the decoded filename on LIMIT_FILE_SIZE - #1478
Open
MaxFreedomPollard wants to merge 1 commit into
Open
fix: report the decoded filename on LIMIT_FILE_SIZE#1478MaxFreedomPollard wants to merge 1 commit into
MaxFreedomPollard wants to merge 1 commit into
Conversation
A LIMIT_FILE_SIZE error carried the raw client-supplied filename, still
carrying the WHATWG %0A, %0D and %22 escapes, while file.originalname and
LIMIT_UNEXPECTED_FILE carried the unescaped name. Uploading `file%22.ext`
over the size limit produced err.filename === 'file%22.ext' where
LIMIT_UNEXPECTED_FILE for the same upload produced 'file".ext'.
decodeFormDataName was applied only where file.originalname is built, so the
two abortWithCode('LIMIT_FILE_SIZE', ...) calls in lib/make-middleware.js
passed busboy's raw `filename` instead. Decode once at the top of the file
handler and use that value for file.originalname and for both errors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
LIMIT_FILE_SIZEerror reports the filename with the WHATWG%0A,%0Dand%22escapes still in it, whilefile.originalnameandLIMIT_UNEXPECTED_FILEreport the unescaped name. Upload a file calledfile".extthat is overlimits.fileSizeand you geterr.filename === 'file%22.ext'; send the same file to a field the middleware does not expect and you geterr.filename === 'file".ext'. The README says errors about a specific file expose the client-supplied name infilenameand to treat it as untrusted input "likefile.originalname", so those two should be the same string.The cause is that
decodeFormDataNameis called in exactly one place,lib/make-middleware.js:298, where thefileobject is built. The twoabortWithCode('LIMIT_FILE_SIZE', ...)calls, at line 282 in thelimitlistener and line 324 in thefileFiltercallback, pass busboy's rawfilenameinstead. The decoding landed infix: decode WHATWG-escaped characters in file originalnameanderr.filenamelanded just after infeat: add filename to file errors, which picked up the variable that was already in scope.The fix decodes once at the top of the
filehandler intooriginalnameand uses that forfile.originalnameand for both errors. busboy passesfilenameasundefinedfor a part that carries no file, so the decode is guarded; that part returns at the existingif (!filename)check and never reaches an error that names a file.Verification on Node 22.23.2, macOS.
npx mocha --exit test/filename-decoding.json unmodifiedmainwith only the new tests applied fails both of them,+ 'file%22.ext'against- 'file".ext'and+ 'a%0D%0Ab.ext'against- 'a\r\nb.ext', and passes with the change.npm testgoes from 132 passing to 134 passing with 2 pending and no failures.npm run lintis clean. The second test uses an asyncfileFilterso it exercises the other call site, the one wherelimitfires while the filter is still pending.