Skip to content

Commit

Permalink
Merge pull request #1060 from jfernandez/jfernandez/duplicate-host-he…
Browse files Browse the repository at this point in the history
…aders

Block requests with multiple Host headers
  • Loading branch information
jfernandez authored May 26, 2021
2 parents 7f14d75 + 72bce0d commit 849a388
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import static com.netflix.netty.common.HttpLifecycleChannelHandler.CompleteReason.SESSION_COMPLETE;
import static com.netflix.zuul.netty.server.http2.Http2OrHttpHandler.PROTOCOL_NAME;

import com.netflix.netty.common.HttpLifecycleChannelHandler;
import com.netflix.netty.common.SourceAddressChannelHandler;
import com.netflix.netty.common.ssl.SslHandshakeInfo;
import com.netflix.netty.common.throttle.RejectionUtils;
Expand Down Expand Up @@ -133,7 +132,7 @@ private void channelReadInternal(final ChannelHandlerContext ctx, Object msg) th
if (clientRequest.decoderResult().isFailure()) {
LOG.warn(
"Invalid http request. clientRequest = {} , uri = {}, info = {}",
clientRequest.toString(),
clientRequest,
clientRequest.uri(),
ChannelUtils.channelInfoForLogging(ctx.channel()),
clientRequest.decoderResult().cause());
Expand All @@ -159,6 +158,19 @@ private void channelReadInternal(final ChannelHandlerContext ctx, Object msg) th
ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
zuulRequest.getContext().setError(ze);
zuulRequest.getContext().setShouldSendErrorResponse(true);
} else if (zuulRequest.getHeaders().getAll(HttpHeaderNames.HOST.toString()).size() > 1) {
LOG.debug(
"Multiple Host headers. clientRequest = {} , uri = {}, info = {}",
clientRequest,
clientRequest.uri(),
ChannelUtils.channelInfoForLogging(ctx.channel()));
final ZuulException ze = new ZuulException("Multiple Host headers");
ze.setStatusCode(HttpResponseStatus.BAD_REQUEST.code());
StatusCategoryUtils.setStatusCategory(
zuulRequest.getContext(),
ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
zuulRequest.getContext().setError(ze);
zuulRequest.getContext().setShouldSendErrorResponse(true);
}

handleExpect100Continue(ctx, clientRequest);
Expand Down Expand Up @@ -206,7 +218,7 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc
}

if (reason == CompleteReason.PIPELINE_REJECT && zuulRequest != null) {
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_PIPELINE_REJECT);
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_PIPELINE_REJECT);
}

if (reason != SESSION_COMPLETE && zuulRequest != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,35 @@ public void maxHeaderSizeExceeded_setBadRequestStatus() {
ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
}

@Test
public void multipleHostHeaders_setBadRequestStatus() {
ClientRequestReceiver receiver = new ClientRequestReceiver(null);
EmbeddedChannel channel = new EmbeddedChannel(new HttpRequestEncoder());
PassportLoggingHandler loggingHandler = new PassportLoggingHandler(new DefaultRegistry());

// Required for messages
channel.attr(SourceAddressChannelHandler.ATTR_SERVER_LOCAL_PORT).set(1234);
channel.pipeline().addLast(new HttpServerCodec());
channel.pipeline().addLast(receiver);
channel.pipeline().addLast(loggingHandler);

HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/post");
httpRequest.headers().add("Host", "foo.bar.com");
httpRequest.headers().add("Host", "bar.foo.com");

channel.writeOutbound(httpRequest);
ByteBuf byteBuf = channel.readOutbound();
channel.writeInbound(byteBuf);
channel.readInbound();
channel.close();

HttpRequestMessage request = ClientRequestReceiver.getRequestFromChannel(channel);
SessionContext context = request.getContext();
assertEquals(StatusCategoryUtils.getStatusCategory(context),
ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
assertEquals("Multiple Host headers", context.getError().getMessage());
}

@Test
public void setStatusCategoryForHttpPipelining() {

Expand Down

0 comments on commit 849a388

Please sign in to comment.