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