From 696f063c5e9157fd10859515da00fd8bd190d76d Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Thu, 23 Aug 2018 16:46:07 +0200 Subject: [PATCH] http,https: protect against slow headers attack CVE-2018-12122 An attacker can send a char/s within headers and exahust the resources (file descriptors) of a system even with a tight max header length protection. This PR destroys a socket if it has not received the headers in 40s. PR-URL: https://github.com/nodejs-private/node-private/pull/151 Ref: https://github.com/nodejs-private/node-private/pull/144 Reviewed-By: Sam Roberts Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- doc/api/http.md | 20 +++++++ doc/api/https.md | 7 +++ lib/_http_server.js | 22 +++++++- lib/https.js | 2 + lib/internal/http.js | 33 ++++++++---- test/async-hooks/test-graph.http.js | 2 +- test/parallel/test-http-slow-headers.js | 56 +++++++++++++++++++ test/parallel/test-https-slow-headers.js | 69 ++++++++++++++++++++++++ 8 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 test/parallel/test-http-slow-headers.js create mode 100644 test/parallel/test-https-slow-headers.js diff --git a/doc/api/http.md b/doc/api/http.md index 9b0be0b61bccc8..9dc46b13f34ccf 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -882,6 +882,26 @@ added: v0.7.0 Limits maximum incoming headers count. If set to 0 - no limit will be applied. +### server.headersTimeout + + +* {number} **Default:** `40000` + +Limit the amount of time the parser will wait to receive the complete HTTP +headers. + +In case of inactivity, the rules defined in [server.timeout][] apply. However, +that inactivity based timeout would still allow the connection to be kept open +if the headers are being sent very slowly (by default, up to a byte per 2 +minutes). In order to prevent this, whenever header data arrives an additional +check is made that more than `server.headersTimeout` milliseconds has not +passed since the connection was established. If the check fails, a `'timeout'` +event is emitted on the server object, and (by default) the socket is destroyed. +See [server.timeout][] for more information on how timeout behaviour can be +customised. + ### server.setTimeout([msecs][, callback])