Merge pull request from GHSA-f256-j965-7f32

Motivation:

We also need to ensure that all the header validation is done when a single header with the endStream flag is received

Modifications:

- Adjust code to always enforce the validation
- Add more unit tests

Result:

Always correctly validate
This commit is contained in:
Norman Maurer 2021-03-30 09:40:47 +02:00 committed by GitHub
parent 5867de70d7
commit b0fa4d5aab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 2 deletions

View File

@ -353,10 +353,13 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
short weight, boolean exclusive, int padding, boolean endOfStream) throws Http2Exception {
Http2Stream stream = connection.stream(streamId);
boolean allowHalfClosedRemote = false;
boolean isTrailers = false;
if (stream == null && !connection.streamMayHaveExisted(streamId)) {
stream = connection.remote().createStream(streamId, endOfStream);
// Allow the state to be HALF_CLOSE_REMOTE if we're creating it in that state.
allowHalfClosedRemote = stream.state() == HALF_CLOSED_REMOTE;
} else if (stream != null) {
isTrailers = stream.isHeadersReceived();
}
if (shouldIgnoreHeadersOrDataFrame(ctx, streamId, stream, "HEADERS")) {
@ -394,7 +397,7 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
stream.state());
}
if (!stream.isHeadersReceived()) {
if (!isTrailers) {
// extract the content-length header
List<? extends CharSequence> contentLength = headers.getAll(HttpHeaderNames.CONTENT_LENGTH);
if (contentLength != null && !contentLength.isEmpty()) {

View File

@ -224,10 +224,53 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
@Test
public void headerMultipleContentLengthValidationShouldPropagate() {
headerMultipleContentLengthValidationShouldPropagate(false);
}
@Test
public void headerMultipleContentLengthValidationShouldPropagateWithEndStream() {
headerMultipleContentLengthValidationShouldPropagate(true);
}
private void headerMultipleContentLengthValidationShouldPropagate(boolean endStream) {
LastInboundHandler inboundHandler = new LastInboundHandler();
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
try {
inboundHandler.checkException();
fail();
} catch (Exception e) {
assertThat(e, CoreMatchers.<Exception>instanceOf(StreamException.class));
}
assertNull(inboundHandler.readInbound());
assertFalse(channel.isActive());
}
@Test
public void headerPlusSignContentLengthValidationShouldPropagate() {
headerSignContentLengthValidationShouldPropagateWithEndStream(false, false);
}
@Test
public void headerPlusSignContentLengthValidationShouldPropagateWithEndStream() {
headerSignContentLengthValidationShouldPropagateWithEndStream(false, true);
}
@Test
public void headerMinusSignContentLengthValidationShouldPropagate() {
headerSignContentLengthValidationShouldPropagateWithEndStream(true, false);
}
@Test
public void headerMinusSignContentLengthValidationShouldPropagateWithEndStream() {
headerSignContentLengthValidationShouldPropagateWithEndStream(true, true);
}
private void headerSignContentLengthValidationShouldPropagateWithEndStream(boolean minus, boolean endStream) {
LastInboundHandler inboundHandler = new LastInboundHandler();
request.add(HttpHeaderNames.CONTENT_LENGTH, (minus ? "-" : "+") + 1);
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
try {
inboundHandler.checkException();
fail();