@@ -43,6 +43,10 @@ var parsers = new FreeList('parsers', 1000, function() {
4343 parser . _headers = [ ] ;
4444 parser . _url = '' ;
4545
46+ // Limit incoming headers count as it may cause
47+ // hash collision DoS
48+ parser . maxHeadersCount = 1000 ;
49+
4650 // Only called in the slow case where slow means
4751 // that the request headers were either fragmented
4852 // across multiple TCP packets or too large to be
@@ -78,7 +82,14 @@ var parsers = new FreeList('parsers', 1000, function() {
7882 parser . incoming . httpVersion = info . versionMajor + '.' + info . versionMinor ;
7983 parser . incoming . url = url ;
8084
81- for ( var i = 0 , n = headers . length ; i < n ; i += 2 ) {
85+ var n = headers . length ;
86+
87+ // If parser.maxHeadersCount <= 0 - assume that there're no limit
88+ if ( parser . maxHeadersCount > 0 ) {
89+ n = Math . min ( n , parser . maxHeadersCount << 1 ) ;
90+ }
91+
92+ for ( var i = 0 ; i < n ; i += 2 ) {
8293 var k = headers [ i ] ;
8394 var v = headers [ i + 1 ] ;
8495 parser . incoming . _addHeaderLine ( k . toLowerCase ( ) , v ) ;
@@ -1158,6 +1169,11 @@ ClientRequest.prototype.onSocket = function(socket) {
11581169 parser . incoming = null ;
11591170 req . parser = parser ;
11601171
1172+ // Propagate headers limit from request object to parser
1173+ if ( req . maxHeadersCount ) {
1174+ parser . maxHeadersCount = req . maxHeadersCount ;
1175+ }
1176+
11611177 socket . _httpMessage = req ;
11621178 // Setup "drain" propogation.
11631179 httpSocketSetup ( socket ) ;
@@ -1444,6 +1460,11 @@ function connectionListener(socket) {
14441460 parser . socket = socket ;
14451461 parser . incoming = null ;
14461462
1463+ // Propagate headers limit from server instance to parser
1464+ if ( this . maxHeadersCount ) {
1465+ parser . maxHeadersCount = this . maxHeadersCount ;
1466+ }
1467+
14471468 socket . addListener ( 'error' , function ( e ) {
14481469 self . emit ( 'clientError' , e ) ;
14491470 } ) ;
0 commit comments