Ralph,

On 5/27/22 18:31, Ralph Atallah wrote:
I suspect that if we were to take the time to set up a proxy,
according to RFC7230, we would be able to get the absolute-form to
reach the Tomcat code and in that case, based on reading the
AbostractHttp11Processor class, I suspect the allowHostHeaderMismatch
will kick in and will behave correctly.  So I doubt that there is a
bug to report at this stage, at least not from my observation.
Thanks for the confirmation.

However, I wonder what all of this means.  Could it be that the Host
header injection or Host header attack issue can only occur when
absolute-form is used, i.e. mostly when proxies are set up?  Both you
and Mark stated that with origin-form there is nothing to compare the
Host header to, which makes sense.  Any thoughts on this assessment?

Well, if the client doesn't send a fully-qualified URL in the request line, then there is nothing to compare the Host header to.

I wonder what you think the "Host header attack" is, and how cross-checking against the URL would help.

Let's say the request looks like this:

GET http://example.com/some-resource
Host: attacker.com

Okay, this looks fishy and you can protect against it by rejecting the request. This is what Tomcat already does.

But how about this one?

GET http://attacker.com/some-resource
Host: attacker.com

What do you want to do, there? The request came to you, but it looks like it should have gone to attacker.com. If you want to reject it, you have to take other measures (which is what Mark was trying to explain in his responses).

No legitimate client is going to send you garbage, so you don't have to worry about e.g. Google Chrome sending you a bad request.

Anyone trying to attack you isn't going to provide convenient cross-checking information (e.g. host-in-request and host-in-Host-header) for you.

And finally, if you aren't validating the Host against a list of pre-defined allowed-hosts, then what's the point of even worrying about cross-checking?

If you aren't setting-up an allow-list, then how can you prevent requests like this from being processed (perhaps badly) by your application:

GET /some-resource
Host: attacker.com

?

I see under separate cover you have shown how you were able to use Tomcat's existing virtual-hosting configuration to explicitly allow only certain hosts. That seems like the best way for you to avoid mischief.

The primary attack vector I can see here is an intentionally malicious reverse proxy which is accepting requests at attacker.com and proxying them to YOUR service in order to trick users into sending information to them instead of you. If they can do that, they are already mounting a MitM against you and no amount of checking host headers is going to solve that problem.

-chris

-----Original Message-----
From: Christopher Schultz <ch...@christopherschultz.net>
Sent: Friday, May 27, 2022 4:26 PM
To: users@tomcat.apache.org
Subject: Re: allowHostHeaderMismatch option only works if the Host Header has 
an http or https prefix

WARNING: This email originated from outside of CallMiner. Do not click any links or 
open any attachments unless you recognize the sender and know that the content is 
safe. Please report suspicious emails to: reportsuspiciousema...@callminer.com 
<mailto:reportsuspiciousema...@callminer.com>

Mark,

On 5/27/22 3:13 AM, Mark Thomas wrote:
On 27/05/2022 02:00, Ralph Atallah wrote:
Hi Mark,

Thanks again for the prompt response.

You wrote below:  "If the original request only has a Host header,
then allowHostHeaderMismatch="false" isn't going to do anything
because there is no mismatch.".  I am not clear on what this means.
What should the match be between?  I thought the comparison for the
match was between the URL's hostname, i.e. "example.com" in the
http://example.com/myapp URL, and the Host header value which is
"attacker.com".  If that understanding is incorrect, please point me
in the right direction of what it should be.

The check is that the host in the request URI (if present) is
consistent with the Host header. Nothing more, nothing less.

HTTP requests may or may not include the host in the request URI.

The host named in the the headers of an HTTP request is completely
independent of the host name used to establish the connection to the
web server.

The AbstractHttp11Processor class does not get to the
allowHostHeaderMismatch detection code because the uriBC (URI
ByteChunk) that it reads is expecting an absolute URL
(http://example.com/myapp), but instead, it is getting a relative one
/myapp.  The reason I say the code expects an absolute URL is because
it checks for and "http" string at the beginning.  This makes me
wonder whether there is a setting that controls that URI format,
absolute or relative.

Your understanding of the HTTP protocol is flawed. You may wish to
read RFC 7230. Specifically:

https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.1
and
https://datatracker.ietf.org/doc/html/rfc7230#section-5.3

Requests with the URI in origin-form do not include a host in the URI.

The purpose of allowHostHeaderMismatch is to ensure that when the
request URI is in absolute-form that the request URI is consistent
with the Host header.

Regarding the addition of a filter that you propose, we have an
existing one in our application, but by the time it is reached, the
URL that we see is already http://attacker.com/myapp, i.e. already
"redirected".

There has been no redirect. The URI reported is a combination of the
Host header and request URI received.

  Technically we could check there against a whitelist, but this would
make the solution less out-of-the box, and more needy of user
configuration in our app.  We prefer an out-of-the-box secure solution.

Any thoughts on the above?

What you want isn't possible.

Actually, I think what Ralph is requesting is exactly what Tomcat is providing 
in the form of allowHostHeaderMismatch (when set to false).

The only problem is that Ralph is saying it's not working because the URI in 
the request doesn't contain a hostname *at all* (because it's optional). So 
there is nothing to check. Browsers don't bother to send the optional 
protocol/hostname/port/etc and instead send the relative URI -- relative to the 
Host header (no coincidentally).

If you (Ralph) can reproduce this with wc or telnet where you can force the URI 
to be absolute *and* provide a conflicting Host header, then I think you have 
grounds for a bug report.

If you want requests to be rejected unless the Host header is on a
user defined allow list (presumably the set of DNS names defined for
the host), then you are going to have to provide a means for the user
to provide that configuration.

I don't think it being requested, here. It may be an aim of their application to do such 
things, but that wasn't a part of the initial request ("prevent host header 
injection" -- which is very strangely worded).

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to