Skip to content

Commit a319168

Browse files
addaleaxBethGriggs
authored andcommittedAug 15, 2019
http2: consider 0-length non-end DATA frames an error
This is intended to mitigate CVE-2019-9518. Backport-PR-URL: #29124 PR-URL: #29122 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 156f2f3 commit a319168

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed
 

‎src/node_http2.cc

+7-8
Original file line numberDiff line numberDiff line change
@@ -1031,8 +1031,7 @@ int Http2Session::OnFrameReceive(nghttp2_session* handle,
10311031
frame->hd.type);
10321032
switch (frame->hd.type) {
10331033
case NGHTTP2_DATA:
1034-
session->HandleDataFrame(frame);
1035-
break;
1034+
return session->HandleDataFrame(frame);
10361035
case NGHTTP2_PUSH_PROMISE:
10371036
// Intentional fall-through, handled just like headers frames
10381037
case NGHTTP2_HEADERS:
@@ -1408,18 +1407,18 @@ void Http2Session::HandlePriorityFrame(const nghttp2_frame* frame) {
14081407
// Called by OnFrameReceived when a complete DATA frame has been received.
14091408
// If we know that this was the last DATA frame (because the END_STREAM flag
14101409
// is set), then we'll terminate the readable side of the StreamBase.
1411-
inline void Http2Session::HandleDataFrame(const nghttp2_frame* frame) {
1410+
int Http2Session::HandleDataFrame(const nghttp2_frame* frame) {
14121411
int32_t id = GetFrameID(frame);
14131412
DEBUG_HTTP2SESSION2(this, "handling data frame for stream %d", id);
14141413
Http2Stream* stream = FindStream(id);
14151414

1416-
// If the stream has already been destroyed, do nothing
1417-
if (stream->IsDestroyed())
1418-
return;
1419-
1420-
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
1415+
if (!stream->IsDestroyed() && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
14211416
stream->EmitData(UV_EOF, Local<Object>(), Local<Object>());
1417+
} else if (frame->hd.length == 0 &&
1418+
!IsReverted(SECURITY_REVERT_CVE_2019_9518)) {
1419+
return 1; // Consider 0-length frame without END_STREAM an error.
14221420
}
1421+
return 0;
14231422
}
14241423

14251424

‎src/node_http2.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -940,14 +940,14 @@ class Http2Session : public AsyncWrap {
940940
size_t maxPayloadLen);
941941

942942
// Frame Handler
943-
inline void HandleDataFrame(const nghttp2_frame* frame);
944-
inline void HandleGoawayFrame(const nghttp2_frame* frame);
945-
inline void HandleHeadersFrame(const nghttp2_frame* frame);
946-
inline void HandlePriorityFrame(const nghttp2_frame* frame);
947-
inline void HandleSettingsFrame(const nghttp2_frame* frame);
948-
inline void HandlePingFrame(const nghttp2_frame* frame);
949-
inline void HandleAltSvcFrame(const nghttp2_frame* frame);
950-
inline void HandleOriginFrame(const nghttp2_frame* frame);
943+
int HandleDataFrame(const nghttp2_frame* frame);
944+
void HandleGoawayFrame(const nghttp2_frame* frame);
945+
void HandleHeadersFrame(const nghttp2_frame* frame);
946+
void HandlePriorityFrame(const nghttp2_frame* frame);
947+
void HandleSettingsFrame(const nghttp2_frame* frame);
948+
void HandlePingFrame(const nghttp2_frame* frame);
949+
void HandleAltSvcFrame(const nghttp2_frame* frame);
950+
void HandleOriginFrame(const nghttp2_frame* frame);
951951

952952
// nghttp2 callbacks
953953
static inline int OnBeginHeadersCallback(

‎src/node_revert.h

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

0 commit comments

Comments
 (0)
Please sign in to comment.