File tree 2 files changed +19
-5
lines changed
2 files changed +19
-5
lines changed Original file line number Diff line number Diff line change @@ -24,10 +24,12 @@ function headerValueNormalize (potentialValue) {
24
24
// To normalize a byte sequence potentialValue, remove
25
25
// any leading and trailing HTTP whitespace bytes from
26
26
// 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 ] + / , '' )
31
33
}
32
34
33
35
function fill ( headers , object ) {
Original file line number Diff line number Diff line change @@ -666,6 +666,18 @@ tap.test('invalid headers', (t) => {
666
666
t . end ( )
667
667
} )
668
668
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
+
669
681
tap . test ( 'Headers.prototype.getSetCookie' , ( t ) => {
670
682
t . test ( 'Mutating the returned list does not affect the set-cookie list' , ( t ) => {
671
683
const h = new Headers ( [
@@ -682,4 +694,4 @@ tap.test('Headers.prototype.getSetCookie', (t) => {
682
694
} )
683
695
684
696
t . end ( )
685
- } )
697
+ } )
You can’t perform that action at this time.
0 commit comments