Request timeout if a single header exceeds the max-http-header-size limit
- Version: 10.15.1
- Platform: 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64
- Subsystem: http
If a request header exceeds the max-http-header-size in Node 10.15.1 and 10.15.0 the request hangs leaving the socket open until the server times out. This seems like it could be a potential DoS attack vector. On Node 10.14.1 a 400 response is received as expected. The code below demonstrates the issue. If you run the code on 10.14.1 both requests will return immediately with a 400 as expected. On 10.15.1 the second request times out.
You can grab the test script from here also. https://github.com/natedanner/node-max-header-timeout/blob/master/server.js
const http = require('http'); const port = 3000; const server = http.createServer((req, res) => { res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); res.end('Hello World\n'); }) server.listen(port, () => { console.log(`Listening on ${port}`); // Headers that together exceed default 8k limit const defaultHeaders = { 'FOO': '6'.repeat(8100), 'BAR': '6'.repeat(8192) }; function callServer(callerName, headers) { return http.get('http://localhost:3000', { headers }, (response) => { console.log(callerName, 'responded with:', response.statusCode); }); } const excessHeadersRequest = callServer('EXCESS_HEADER', defaultHeaders); excessHeadersRequest.setTimeout(2000, () => { console.log('SHOULD NOT SEE THIS'); }); // If you exceed header limit on a single header by 1 then the request hangs open defaultHeaders['BAR'] += '6' const headerTimeoutRequest = callServer('EXCESS_HEADER_TIMEOUT', defaultHeaders); headerTimeoutRequest.setTimeout(2000, () => { console.log('EXCESS_HEADER_TIMEOUT CALL TIMED OUT!'); }); });