diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-08-11 00:10:54 +0300 |
---|---|---|
committer | Michaƫl Zasso <targos@protonmail.com> | 2019-08-15 10:51:52 +0300 |
commit | b4cfa521b8b0fbe5ee5815fcac3614cc0960f7d9 (patch) | |
tree | ee010c753c6f748befb870fc6873313a54636f4c /src/node_http2.cc | |
parent | a54af9e1888c01f9a9553eb0e91664a249cabe96 (diff) |
http2: handle 0-length headers better
Ignore headers with 0-length names and track memory for headers
the way we track it for other HTTP/2 session memory too.
This is intended to mitigate CVE-2019-9516.
PR-URL: https://github.com/nodejs/node/pull/29122
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_http2.cc')
-rw-r--r-- | src/node_http2.cc | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/node_http2.cc b/src/node_http2.cc index 058ae1f1909..e184a3ce82c 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -1309,6 +1309,8 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) { return; std::vector<nghttp2_header> headers(stream->move_headers()); + DecrementCurrentSessionMemory(stream->current_headers_length_); + stream->current_headers_length_ = 0; // The headers are passed in above as a queue of nghttp2_header structs. // The following converts that into a JS array with the structure: @@ -1942,6 +1944,7 @@ Http2Stream::~Http2Stream() { if (session_ == nullptr) return; Debug(this, "tearing down stream"); + session_->DecrementCurrentSessionMemory(current_headers_length_); session_->RemoveStream(this); session_ = nullptr; } @@ -1956,6 +1959,7 @@ std::string Http2Stream::diagnostic_name() const { void Http2Stream::StartHeaders(nghttp2_headers_category category) { Debug(this, "starting headers, category: %d", id_, category); CHECK(!this->IsDestroyed()); + session_->DecrementCurrentSessionMemory(current_headers_length_); current_headers_length_ = 0; current_headers_.clear(); current_headers_category_ = category; @@ -2225,8 +2229,12 @@ bool Http2Stream::AddHeader(nghttp2_rcbuf* name, CHECK(!this->IsDestroyed()); if (this->statistics_.first_header == 0) this->statistics_.first_header = uv_hrtime(); - size_t length = nghttp2_rcbuf_get_buf(name).len + - nghttp2_rcbuf_get_buf(value).len + 32; + size_t name_len = nghttp2_rcbuf_get_buf(name).len; + if (name_len == 0 && !IsReverted(SECURITY_REVERT_CVE_2019_9516)) { + return true; // Ignore headers with empty names. + } + size_t value_len = nghttp2_rcbuf_get_buf(value).len; + size_t length = name_len + value_len + 32; // A header can only be added if we have not exceeded the maximum number // of headers and the session has memory available for it. if (!session_->IsAvailableSessionMemory(length) || @@ -2242,6 +2250,7 @@ bool Http2Stream::AddHeader(nghttp2_rcbuf* name, nghttp2_rcbuf_incref(name); nghttp2_rcbuf_incref(value); current_headers_length_ += length; + session_->IncrementCurrentSessionMemory(length); return true; } |