File tree Expand file tree Collapse file tree 2 files changed +19
-5
lines changed Expand file tree Collapse file tree 2 files changed +19
-5
lines changed Original file line number Diff line number Diff 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
3335function fill ( headers , object ) {
Original file line number Diff line number Diff 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+
669681tap . 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+ } )
You can’t perform that action at this time.
0 commit comments