From fc56552b2a3a1cf05b0999708c628fa0d40edd13 Mon Sep 17 00:00:00 2001 From: Cesar Blum Silveira Date: Wed, 20 Sep 2017 18:40:19 -0700 Subject: [PATCH] HTTP/2: close connection on PING frame with non-zero stream ID. --- .../Internal/Http2/Http2Connection.cs | 5 +++++ .../Http2ConnectionTests.cs | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Kestrel.Core/Internal/Http2/Http2Connection.cs b/src/Kestrel.Core/Internal/Http2/Http2Connection.cs index 87adced245..cf7f25f287 100644 --- a/src/Kestrel.Core/Internal/Http2/Http2Connection.cs +++ b/src/Kestrel.Core/Internal/Http2/Http2Connection.cs @@ -386,6 +386,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR); } + if (_incomingFrame.StreamId != 0) + { + throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR); + } + if (_incomingFrame.Length != 8) { throw new Http2ConnectionErrorException(Http2ErrorCode.FRAME_SIZE_ERROR); diff --git a/test/Kestrel.Core.Tests/Http2ConnectionTests.cs b/test/Kestrel.Core.Tests/Http2ConnectionTests.cs index df4621a8b2..5a8ea479a3 100644 --- a/test/Kestrel.Core.Tests/Http2ConnectionTests.cs +++ b/test/Kestrel.Core.Tests/Http2ConnectionTests.cs @@ -887,6 +887,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false); } + [Fact] + public async Task PING_Received_StreamIdNotZero_ConnectionError() + { + await InitializeConnectionAsync(_noopApplication); + + await SendPingWithInvalidStreamIdAsync(streamId: 1); + + await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false); + } + [Theory] [InlineData(0)] [InlineData(1)] @@ -1427,6 +1437,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests return SendAsync(pingFrame.Raw); } + private Task SendPingWithInvalidStreamIdAsync(int streamId) + { + Assert.NotEqual(0, streamId); + + var pingFrame = new Http2Frame(); + pingFrame.PreparePing(Http2PingFrameFlags.NONE); + pingFrame.StreamId = streamId; + return SendAsync(pingFrame.Raw); + } + private Task SendPriorityAsync(int streamId) { var priorityFrame = new Http2Frame();