Enforce max frame size #2651
This commit is contained in:
parent
810a302e66
commit
a217206f1f
|
|
@ -497,9 +497,6 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l
|
|||
<data name="MultipleCertificateSources" xml:space="preserve">
|
||||
<value>The endpoint {endpointName} specified multiple certificate sources.</value>
|
||||
</data>
|
||||
<data name="Http2NotSupported" xml:space="preserve">
|
||||
<value>HTTP/2 support is experimental, see https://go.microsoft.com/fwlink/?linkid=866785 to enable it.</value>
|
||||
</data>
|
||||
<data name="WritingToResponseBodyAfterResponseCompleted" xml:space="preserve">
|
||||
<value>Cannot write to the response body, the response has completed.</value>
|
||||
</data>
|
||||
|
|
@ -518,4 +515,7 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l
|
|||
<data name="ConnectionTimedOutByServer" xml:space="preserve">
|
||||
<value>The connection was timed out by the server.</value>
|
||||
</data>
|
||||
<data name="Http2ErrorFrameOverLimit" xml:space="preserve">
|
||||
<value>The received frame size of {size} exceeds the limit {limit}.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
{
|
||||
if (!readableBuffer.IsEmpty)
|
||||
{
|
||||
if (Http2FrameReader.ReadFrame(readableBuffer, _incomingFrame, out consumed, out examined))
|
||||
if (Http2FrameReader.ReadFrame(readableBuffer, _incomingFrame, _serverSettings.MaxFrameSize, out consumed, out examined))
|
||||
{
|
||||
Log.LogTrace($"Connection id {ConnectionId} received {_incomingFrame.Type} frame with flags 0x{_incomingFrame.Flags:x} and length {_incomingFrame.Length} for stream ID {_incomingFrame.StreamId}");
|
||||
await ProcessFrameAsync<TContext>(application);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
{
|
||||
public static class Http2FrameReader
|
||||
{
|
||||
public static bool ReadFrame(ReadOnlySequence<byte> readableBuffer, Http2Frame frame, out SequencePosition consumed, out SequencePosition examined)
|
||||
public static bool ReadFrame(ReadOnlySequence<byte> readableBuffer, Http2Frame frame, uint maxFrameSize, out SequencePosition consumed, out SequencePosition examined)
|
||||
{
|
||||
consumed = readableBuffer.Start;
|
||||
examined = readableBuffer.End;
|
||||
|
|
@ -22,6 +22,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
var headerSlice = readableBuffer.Slice(0, Http2Frame.HeaderLength);
|
||||
headerSlice.CopyTo(frame.Raw);
|
||||
|
||||
if (frame.Length > maxFrameSize)
|
||||
{
|
||||
throw new Http2ConnectionErrorException(CoreStrings.FormatHttp2ErrorFrameOverLimit(frame.Length, maxFrameSize), Http2ErrorCode.FRAME_SIZE_ERROR);
|
||||
}
|
||||
|
||||
if (readableBuffer.Length < Http2Frame.HeaderLength + frame.Length)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1778,20 +1778,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
internal static string FormatMultipleCertificateSources(object endpointName)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("MultipleCertificateSources", "endpointName"), endpointName);
|
||||
|
||||
/// <summary>
|
||||
/// HTTP/2 support is experimental, see https://go.microsoft.com/fwlink/?linkid=866785 to enable it.
|
||||
/// </summary>
|
||||
internal static string Http2NotSupported
|
||||
{
|
||||
get => GetString("Http2NotSupported");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HTTP/2 support is experimental, see https://go.microsoft.com/fwlink/?linkid=866785 to enable it.
|
||||
/// </summary>
|
||||
internal static string FormatHttp2NotSupported()
|
||||
=> GetString("Http2NotSupported");
|
||||
|
||||
/// <summary>
|
||||
/// Cannot write to the response body, the response has completed.
|
||||
/// </summary>
|
||||
|
|
@ -1876,6 +1862,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
internal static string FormatConnectionTimedOutByServer()
|
||||
=> GetString("ConnectionTimedOutByServer");
|
||||
|
||||
/// <summary>
|
||||
/// The received frame size of {size} exceeds the limit {limit}.
|
||||
/// </summary>
|
||||
internal static string Http2ErrorFrameOverLimit
|
||||
{
|
||||
get => GetString("Http2ErrorFrameOverLimit");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The received frame size of {size} exceeds the limit {limit}.
|
||||
/// </summary>
|
||||
internal static string FormatHttp2ErrorFrameOverLimit(object size, object limit)
|
||||
=> string.Format(CultureInfo.CurrentCulture, GetString("Http2ErrorFrameOverLimit", "size", "limit"), size, limit);
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -299,6 +299,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
_decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Frame_Received_OverMaxSize_FrameError()
|
||||
{
|
||||
await InitializeConnectionAsync(_echoApplication);
|
||||
|
||||
await StartStreamAsync(1, _browserRequestHeaders, endStream: false);
|
||||
// Manually craft a frame where the size is too large. Our own frame class won't allow this.
|
||||
// See Http2Frame.Length
|
||||
var length = Http2Frame.MinAllowedMaxFrameSize + 1; // Too big
|
||||
var frame = new byte[9 + length];
|
||||
frame[0] = (byte)((length & 0x00ff0000) >> 16);
|
||||
frame[1] = (byte)((length & 0x0000ff00) >> 8);
|
||||
frame[2] = (byte)(length & 0x000000ff);
|
||||
await SendAsync(frame);
|
||||
|
||||
await WaitForConnectionErrorAsync<Http2ConnectionErrorException>(
|
||||
ignoreNonGoAwayFrames: true,
|
||||
expectedLastStreamId: 1,
|
||||
expectedErrorCode: Http2ErrorCode.FRAME_SIZE_ERROR,
|
||||
expectedErrorMessage: CoreStrings.FormatHttp2ErrorFrameOverLimit(length, Http2Frame.MinAllowedMaxFrameSize));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DATA_Received_ReadByStream()
|
||||
{
|
||||
|
|
@ -2794,7 +2816,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
{
|
||||
Assert.True(buffer.Length > 0);
|
||||
|
||||
if (Http2FrameReader.ReadFrame(buffer, frame, out consumed, out examined))
|
||||
if (Http2FrameReader.ReadFrame(buffer, frame, 16_384, out consumed, out examined))
|
||||
{
|
||||
return frame;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue