From a4887f4caf93377a93ec1ae276b1455a7b10641c Mon Sep 17 00:00:00 2001 From: Cesar Blum Silveira Date: Thu, 21 Sep 2017 10:29:43 -0700 Subject: [PATCH] HTTP/2: close connection with PROTOCOL_ERROR when receiving GOAWAY frame with non-zero stream ID. --- .../Internal/Http2/Http2Connection.cs | 5 +++++ .../Kestrel.Core.Tests/Http2ConnectionTests.cs | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Kestrel.Core/Internal/Http2/Http2Connection.cs b/src/Kestrel.Core/Internal/Http2/Http2Connection.cs index cf7f25f287..dcf3aed4ad 100644 --- a/src/Kestrel.Core/Internal/Http2/Http2Connection.cs +++ b/src/Kestrel.Core/Internal/Http2/Http2Connection.cs @@ -406,6 +406,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); + } + Stop(); return Task.CompletedTask; } diff --git a/test/Kestrel.Core.Tests/Http2ConnectionTests.cs b/test/Kestrel.Core.Tests/Http2ConnectionTests.cs index 5a8ea479a3..5cc64cec8c 100644 --- a/test/Kestrel.Core.Tests/Http2ConnectionTests.cs +++ b/test/Kestrel.Core.Tests/Http2ConnectionTests.cs @@ -941,6 +941,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Contains(5, _abortedStreamIds); } + [Fact] + public async Task GOAWAY_Received_StreamIdNonZero_ConnectionError() + { + await InitializeConnectionAsync(_noopApplication); + + await SendInvalidGoAwayFrameAsync(); + + await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false); + } + [Fact] public async Task GOAWAY_Received_InterleavedWithHeaders_ConnectionError() { @@ -1484,6 +1494,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests return SendAsync(frame.Raw); } + private Task SendInvalidGoAwayFrameAsync() + { + var frame = new Http2Frame(); + frame.PrepareGoAway(0, Http2ErrorCode.NO_ERROR); + frame.StreamId = 1; + return SendAsync(frame.Raw); + } + private Task SendWindowUpdateAsync(int streamId, int sizeIncrement) { var frame = new Http2Frame();