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