Skip to content

Commit 5c838c6

Browse files
authored
fix: enforce RFC 2183/7578 compliance for quoted Content-Disposition parameters (#194)
Properly parse Content-Disposition filename parameters by stopping at the closing quote instead of continuing to parse characters after it. This fixes the security issue where filename="payload.jpg".html was incorrectly parsed as payload.jpg.html instead of payload.jpg. The fix ensures that quoted parameter values are correctly terminated at their closing quotes, preventing potential security vulnerabilities from malformed Content-Disposition headers.
1 parent 32c698f commit 5c838c6

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

lib/utils/parseParams.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ function parseParams (str) {
136136
if (inquote) {
137137
inquote = false
138138
state = STATE_KEY
139+
// Skip any remaining characters until we hit a semicolon or end of string
140+
// This ensures we don't include characters after the closing quote
141+
while (i + 1 < len && str[i + 1] !== ';') {
142+
++i
143+
}
139144
} else { inquote = true }
140145
continue
141146
} else { escaping = false }

test/parse-params.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,21 @@ test('parse-params', async t => {
115115
source: 'multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY',
116116
expected: ['multipart/form-data', ['charset', 'utf-8'], ['boundary', '0xKhTmLbOuNdArY']],
117117
what: 'Multiple non-quoted parameters'
118+
},
119+
{
120+
source: 'form-data; name="file"; filename="payload.jpg".html',
121+
expected: ['form-data', ['name', 'file'], ['filename', 'payload.jpg']],
122+
what: 'Improperly quoted filename should stop at closing quote (RFC 2183/7578 compliance)'
123+
},
124+
{
125+
source: 'form-data; name="field"; filename="test.pdf"extra.txt',
126+
expected: ['form-data', ['name', 'field'], ['filename', 'test.pdf']],
127+
what: 'Quoted filename with trailing unquoted text should stop at closing quote'
128+
},
129+
{
130+
source: 'text/plain; charset="utf-8"garbage; boundary=test',
131+
expected: ['text/plain', ['charset', 'utf-8'], ['boundary', 'test']],
132+
what: 'Quoted parameter with trailing garbage should stop at closing quote'
118133
}
119134
]
120135

0 commit comments

Comments
 (0)