[security advisory] $http_host vs $host

Gena Makhomed gmm at csdoc.com
Tue Mar 10 22:29:29 UTC 2015


On 10.03.2015 23:09, Francis Daly wrote:

>> server {
>>     listen 443 ssl;
>>     server_name private.example.com;
>>     location / {
>>       auth_basic "closed site";
>>       auth_basic_user_file conf/htpasswd;
>>       proxy_set_header  Host $http_host;
>>       proxy_pass http://backend;
>>     }
>> }
>>
>> server {
>>     listen 443 ssl;
>>     server_name public.example.com;
>>     location / {
>>       proxy_set_header  Host $http_host;
>>       proxy_pass http://backend;
>>     }
>> }
>>
>> in such configuration anybody can bypass nginx auth_basic restriction
>> and access content from private.example.com without any login/password:
>
> You are correct.
>
> It is possible to construct a scenario where the difference between
> $http_host and $host matters from a security perspective.
>
> It is also possible to construct a scenario where the difference between
> $http_host and $host matters from a correctness perspective.
>

I don't know situations where system administrator need use

proxy_set_header  Host $http_host;

instead of

proxy_set_header  Host $host;

because only $host variable contains correct host name,
and $http_host may be spoofed and contains anything other.

So, for me I create simple rule of nginx configuration:
always use $host in directive proxy_set_header Host
and never use $http_host there.

> The "common" redmine configuration appears to be one of the latter,
> if nginx is not run on port 80 (such as, by using the original example
> config and running nginx as non-root).
>
> If nginx runs on port 80, then everything probably Just Works.
>
> I suspect that if the "proxy_set_header Host" is omitted entirely, then
> the default "proxy_redirect" probably means that everything Just Works,
> whatever port nginx listens on. And the current example config does just
> that, so it's all good.

In redmine settings: https://redmine.example.com/settings
you can select "Host name and path" to use and protocol, HTTP or HTTPS.

>> for fastcgi_pass such bug can be fixed only by using two nginx
>> servers - first for frontend, and second for backend,
>> because nginx send to fastcgi value of $http_host
>
> I think it may be possible for the fastcgi application to avoid that
> confusion -- nginx sends the http headers plus whatever is configured to
> be sent. So, for creation of "redirect" urls back to the client,
> HTTP_HOST may be sensible to use; but for anything where the nginx
> server{} chosen matters, sending $server_name or $host from nginx in a
> well-known fastcgi_param is probably a better option.

Yes, I am talking about protecting of FastCGI application,
from system administrator point of view, - some application,
open source or closed source, and I don't know how reliable code
of this application and want to make it safe and protected from
such spoofed $http_host in HTTP_HOST variable, thanks to FastCGI spec.

-- 
Best regards,
  Gena



More information about the nginx mailing list