Skip to content

Commit 17357d3

Browse files
addaleaxBethGriggs
authored andcommitted
http2: consider 0-length non-end DATA frames an error
This is intended to mitigate CVE-2019-9518. Backport-PR-URL: #29123 PR-URL: #29122 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 460f896 commit 17357d3

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed

src/node_http2.cc

+8-4
Original file line numberDiff line numberDiff line change
@@ -980,8 +980,7 @@ int Http2Session::OnFrameReceive(nghttp2_session* handle,
980980
frame->hd.type);
981981
switch (frame->hd.type) {
982982
case NGHTTP2_DATA:
983-
session->HandleDataFrame(frame);
984-
break;
983+
return session->HandleDataFrame(frame);
985984
case NGHTTP2_PUSH_PROMISE:
986985
// Intentional fall-through, handled just like headers frames
987986
case NGHTTP2_HEADERS:
@@ -1398,13 +1397,18 @@ void Http2Session::HandlePriorityFrame(const nghttp2_frame* frame) {
13981397
// Called by OnFrameReceived when a complete DATA frame has been received.
13991398
// If we know that this was the last DATA frame (because the END_STREAM flag
14001399
// is set), then we'll terminate the readable side of the StreamBase.
1401-
void Http2Session::HandleDataFrame(const nghttp2_frame* frame) {
1400+
int Http2Session::HandleDataFrame(const nghttp2_frame* frame) {
14021401
int32_t id = GetFrameID(frame);
14031402
Debug(this, "handling data frame for stream %d", id);
14041403
Http2Stream* stream = FindStream(id);
14051404

1406-
if (!stream->IsDestroyed() && frame->hd.flags & NGHTTP2_FLAG_END_STREAM)
1405+
if (!stream->IsDestroyed() && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
14071406
stream->EmitRead(UV_EOF);
1407+
} else if (frame->hd.length == 0 &&
1408+
!IsReverted(SECURITY_REVERT_CVE_2019_9518)) {
1409+
return 1; // Consider 0-length frame without END_STREAM an error.
1410+
}
1411+
return 0;
14081412
}
14091413

14101414

src/node_http2.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ class Http2Session : public AsyncWrap, public StreamListener {
889889
size_t maxPayloadLen);
890890

891891
// Frame Handler
892-
void HandleDataFrame(const nghttp2_frame* frame);
892+
int HandleDataFrame(const nghttp2_frame* frame);
893893
void HandleGoawayFrame(const nghttp2_frame* frame);
894894
void HandleHeadersFrame(const nghttp2_frame* frame);
895895
void HandlePriorityFrame(const nghttp2_frame* frame);

src/node_revert.h

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace node {
1818
#define SECURITY_REVERSIONS(XX) \
1919
XX(CVE_2019_9514, "CVE-2019-9514", "HTTP/2 Reset Flood") \
2020
XX(CVE_2019_9516, "CVE-2019-9516", "HTTP/2 0-Length Headers Leak") \
21+
XX(CVE_2019_9518, "CVE-2019-9518", "HTTP/2 Empty DATA Frame Flooding") \
2122
// XX(CVE_2016_PEND, "CVE-2016-PEND", "Vulnerability Title")
2223
// TODO(addaleax): Remove all of the above before Node.js 13 as the comment
2324
// at the start of the file indicates.

0 commit comments

Comments
 (0)