@@ -1305,8 +1305,24 @@ inline void Http2Session::HandlePingFrame(const nghttp2_frame* frame) {
1305
1305
bool ack = frame->hd .flags & NGHTTP2_FLAG_ACK;
1306
1306
if (ack) {
1307
1307
Http2Ping* ping = PopPing ();
1308
- if (ping != nullptr )
1308
+ if (ping != nullptr ) {
1309
1309
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
+ }
1310
1326
}
1311
1327
}
1312
1328
@@ -1317,8 +1333,28 @@ inline void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) {
1317
1333
// If this is an acknowledgement, we should have an Http2Settings
1318
1334
// object for it.
1319
1335
Http2Settings* settings = PopSettings ();
1320
- if (settings != nullptr )
1336
+ if (settings != nullptr ) {
1321
1337
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
+ }
1322
1358
} else {
1323
1359
// Otherwise, notify the session about a new settings
1324
1360
MakeCallback (env ()->onsettings_string (), 0 , nullptr );
0 commit comments