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 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.

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".  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?

Thanks,
Ralph

-----Original Message-----
From: Mark Thomas <ma...@apache.org> 
Sent: Thursday, May 26, 2022 12:21 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>

On 26/05/2022 14:29, Ralph Atallah wrote:
> Hi Mark,
>
> What we are trying to do is to prevent Host header attacks by ensuring that 
> the host name in the http request URL always matches the "Host" header in the 
> request.  If it does not, we are supposed refuse the request and respond with 
> 400 Bad Request as per OWASP recommendations.   Here are some examples:
>
> Normal request
>     GET http://example.com/myapp
>     Host: example.com
>     Expected response:  200 OK
>
> Request with a host header attack
>     GET http://example.com/myapp
>     Host: attacker.com
>     Expected response:  400 Bad Request
>
> The AbstracktHttp11Processor.java class seems to be doing exactly that in the 
> code snippet below:
>
>     if (allowHostHeaderMismatch) {
>           // The requirements of RFC 2616 are being
>           // applied. If the host header and the request
>           // line do not agree, the request line takes
>           // precedence
>           hostValueMB = headers.setValue("host");
>           hostValueMB.setBytes(uriB, uriBCStart + pos, slashPos - pos);
>       } else {
>            // The requirements of RFC 7230 are being
>            // applied. If the host header and the request
>            // line do not agree, trigger a 400 response.
>            badRequest("http11processor.request.inconsistentHosts");
>       }
>
> However, this portion of the code is never reached for the reason mentioned 
> in the previous email.
>
> By the time the request reaches our application, the 
> HttpServletRequest.getRequestURL() returns  http://attacker.com/myapp instead 
> of http://example.com/myapp
> We have enabled the AccessLogValve in server.xml in the hope to see the URL 
> that reaches tomcat, but it seems that we only get the relative URL there, 
> never the absolute one, i.e. we only see /myapp when we print %u for example.
>
> Any tips in this area would be much appreciated.

If the original request only has a Host header, then
allowHostHeaderMismatch="false" isn't going to do anything because there
is no mismatch.

If you want to reject requests that have a Host header that isn't one
you recognize then there are multiple options:

- write a Filter
- write a Valve
- configure a Host (or several) for the requests you want to allow and
   deploy an ROOT to the default host that rejects everything else.

Mark



> Ralph
>
> -----Original Message-----
> From: Mark Thomas <ma...@apache.org>
> Sent: Thursday, May 26, 2022 3:24 AM
> 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>
>
> On 26/05/2022 02:20, Ralph Atallah wrote:
>> Hi,
>>
>> We use Tomcat 7.0.109 and Tomcat 8.5 in our Tomcat based webapp deployments 
>> and we have a new requirement to prevent Host Header injection.  The 
>> allowHostHeaderMismatch option seems the perfect answer to this issue.  
>> However, configuring it in our environment, i.e. in the server.xml connector 
>> tag still does not seem to make it work.
>>
>> Debugging the code, we see that the check for this setting is never even 
>> reached in the 
>> org.apache.coyote.http11.AbstractHttp11Processor.prepareRequest() method.  
>> The reason is in the code snippet below:
>>
>>    ByteChunk uriBC = request.requestURI().getByteChunk();
>>    byte[] uriB = uriBC.getBytes();
>>    if (uriBC.startsWithIgnoreCase("http", 0)) {
>>      ...
>>       if (allowHostHeaderMismatch) {
>>          ...
>>       }
>> }
>>
>> uriBC does not contain the full URL such as http://localhost:8080/myapp, but 
>> rather only the /myapp path, so that if (uriBC.startsWithIgnoreCase("http", 
>> 0)) condition is never met.
>>
>> We are probably missing something very basic, and would really appreciate 
>> some guidance.
>
> I suspect that allowHostHeaderMismatch doesn't do what you think it does.
>
> Exactly what problem are you trying to solve when so say you want to prevent 
> "Host header injection"?
>
> Mark
>
> ---------------------------------------------------------------------
> 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