Skip to content

Commit f2324e5

Browse files
Trottmcollina
andauthored
Merge pull request from GHSA-r6ch-mqf9-qc9w
Refs: https://hackerone.com/bugs?report_id=1784449 Co-authored-by: Matteo Collina <hello@matteocollina.com>
1 parent a2eff05 commit f2324e5

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

lib/fetch/headers.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ function headerValueNormalize (potentialValue) {
2424
// To normalize a byte sequence potentialValue, remove
2525
// any leading and trailing HTTP whitespace bytes from
2626
// potentialValue.
27-
return potentialValue.replace(
28-
/^[\r\n\t ]+|[\r\n\t ]+$/g,
29-
''
30-
)
27+
28+
// Trimming the end with `.replace()` and a RegExp is typically subject to
29+
// ReDoS. This is safer and faster.
30+
let i = potentialValue.length
31+
while (/[\r\n\t ]/.test(potentialValue.charAt(--i)));
32+
return potentialValue.slice(0, i + 1).replace(/^[\r\n\t ]+/, '')
3133
}
3234

3335
function fill (headers, object) {

test/fetch/headers.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,18 @@ tap.test('invalid headers', (t) => {
666666
t.end()
667667
})
668668

669+
tap.test('headers that might cause a ReDoS', (t) => {
670+
t.doesNotThrow(() => {
671+
// This test will time out if the ReDoS attack is successful.
672+
const headers = new Headers()
673+
const attack = 'a' + '\t'.repeat(500_000) + '\ta'
674+
headers.append('fhqwhgads', attack)
675+
})
676+
677+
t.end()
678+
})
679+
680+
669681
tap.test('Headers.prototype.getSetCookie', (t) => {
670682
t.test('Mutating the returned list does not affect the set-cookie list', (t) => {
671683
const h = new Headers([
@@ -682,4 +694,4 @@ tap.test('Headers.prototype.getSetCookie', (t) => {
682694
})
683695

684696
t.end()
685-
})
697+
})

0 commit comments

Comments
 (0)