@@ -1305,8 +1305,24 @@ inline void Http2Session::HandlePingFrame(const nghttp2_frame* frame) {
13051305 bool ack = frame->hd .flags & NGHTTP2_FLAG_ACK;
13061306 if (ack) {
13071307 Http2Ping* ping = PopPing ();
1308- if (ping != nullptr )
1308+ if (ping != nullptr ) {
13091309 ping->Done (true , frame->ping .opaque_data );
1310+ } else {
1311+ // PING Ack is unsolicited. Treat as a connection error. The HTTP/2
1312+ // spec does not require this, but there is no legitimate reason to
1313+ // receive an unsolicited PING ack on a connection. Either the peer
1314+ // is buggy or malicious, and we're not going to tolerate such
1315+ // nonsense.
1316+ Isolate* isolate = env ()->isolate ();
1317+ HandleScope scope (isolate);
1318+ Local<Context> context = env ()->context ();
1319+ Context::Scope context_scope (context);
1320+
1321+ Local<Value> argv[1 ] = {
1322+ Integer::New (isolate, NGHTTP2_ERR_PROTO),
1323+ };
1324+ MakeCallback (env ()->error_string (), arraysize (argv), argv);
1325+ }
13101326 }
13111327}
13121328
@@ -1317,8 +1333,28 @@ inline void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) {
13171333 // If this is an acknowledgement, we should have an Http2Settings
13181334 // object for it.
13191335 Http2Settings* settings = PopSettings ();
1320- if (settings != nullptr )
1336+ if (settings != nullptr ) {
13211337 settings->Done (true );
1338+ } else {
1339+ // SETTINGS Ack is unsolicited. Treat as a connection error. The HTTP/2
1340+ // spec does not require this, but there is no legitimate reason to
1341+ // receive an unsolicited SETTINGS ack on a connection. Either the peer
1342+ // is buggy or malicious, and we're not going to tolerate such
1343+ // nonsense.
1344+ // Note that nghttp2 currently prevents this from happening for SETTINGS
1345+ // frames, so this block is purely defensive just in case that behavior
1346+ // changes. Specifically, unlike unsolicited PING acks, unsolicited
1347+ // SETTINGS acks should *never* make it this far.
1348+ Isolate* isolate = env ()->isolate ();
1349+ HandleScope scope (isolate);
1350+ Local<Context> context = env ()->context ();
1351+ Context::Scope context_scope (context);
1352+
1353+ Local<Value> argv[1 ] = {
1354+ Integer::New (isolate, NGHTTP2_ERR_PROTO),
1355+ };
1356+ MakeCallback (env ()->error_string (), arraysize (argv), argv);
1357+ }
13221358 } else {
13231359 // Otherwise, notify the session about a new settings
13241360 MakeCallback (env ()->onsettings_string (), 0 , nullptr );
0 commit comments