<div dir="ltr"><div class="gmail_default" style="font-size:small;color:rgb(51,51,153)">You specifically configured nginx to pass the Host header ($http_host) to the backend, thus the backend has only this piece of information available...<br></div><div class="gmail_default" style="font-size:small;color:rgb(51,51,153)">If you specified $host to be passed over, you would not have this flaw in your configuration.<br></div><div class="gmail_default" style="font-size:small;color:rgb(51,51,153)">nginx does exactly what you configured. By default there is no such header set for the backend.<br><br></div><div class="gmail_default" style="font-size:small;color:rgb(51,51,153)">Moreover using a Host header as a 'security feature' is... strange at the very least.<br><br></div><div class="gmail_default" style="font-size:small;color:rgb(51,51,153)">The difference between the host (machine) and the Host header is common, and should not be relied on for security. Have you ever played with curl?<br></div><div class="gmail_default" style="font-size:small;color:rgb(51,51,153)">If you use auth_basic for security, you should follow the same process when dealing with the backend. The $remote_user variable allows you to check which user has been authenticated. I would pass that to the backend. No user = no authentication.<br><br></div><div class="gmail_default" style="font-size:small;color:rgb(51,51,153)">The only 'security advisory' I see here is to teach some basic course about security to your sysadmin.<br></div><div class="gmail_extra"><div><div class="gmail_signature"><font size="1"><span style="color:rgb(102,102,102)">---<br></span><b><span style="color:rgb(102,102,102)">B. R.</span></b><span style="color:rgb(102,102,102)"></span></font></div></div>
<br><div class="gmail_quote">On Mon, Mar 9, 2015 at 7:56 PM, Gena Makhomed <span dir="ltr"><<a href="mailto:gmm@csdoc.com" target="_blank">gmm@csdoc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 09.03.2015 19:25, Francis Daly wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Unsafe variable $http_host was used instead of safe one $host<br>
</blockquote>
<br>
I'm not sure how $http_host is less safe than $host. It is proxy_pass'ed<br>
to the "real" redmine server as the Host header. That server must be<br>
able to handle it safely anyway, no?<br>
</blockquote>
<br>
Such configuration allow to spoof nginx built-in server selection rules.<br>
because nginx will use server name from request line, but will provide<br>
to upstream completely different server name, from Host request header.<br>
</blockquote>
<br>
It is true that $http_host is completely controlled by the client, and<br>
$host is mostly controlled by the client. It is true that they can have<br>
different values. I do not see that the difference is a security issue<br>
in this case.<br>
<br>
</blockquote>
<br>
server {<br>
   listen 443 ssl;<br>
   server_name <a href="http://private.example.com" target="_blank">private.example.com</a>;<br>
   location / {<br>
     auth_basic "closed site";<br>
     auth_basic_user_file conf/htpasswd;<br>
     proxy_set_header  Host $http_host;<br>
     proxy_pass <a href="http://backend" target="_blank">http://backend</a>;<br>
   }<br>
}<br>
<br>
server {<br>
   listen 443 ssl;<br>
   server_name <a href="http://public.example.com" target="_blank">public.example.com</a>;<br>
   location / {<br>
     proxy_set_header  Host $http_host;<br>
     proxy_pass <a href="http://backend" target="_blank">http://backend</a>;<br>
   }<br>
}<br>
<br>
in such configuration anybody can bypass nginx auth_basic restriction<br>
and access content from <a href="http://private.example.com" target="_blank">private.example.com</a> without any login/password:<br>
<br>
GET <a href="https://public.example.com/top-secret.pdf" target="_blank">https://public.example.com/<u></u>top-secret.pdf</a> HTTP/1.1<br>
Host: <a href="http://private.example.com" target="_blank">private.example.com</a><br>
<br>
nginx will use host name <a href="http://public.example.com" target="_blank">public.example.com</a> for server selection,<br>
and process request in second server, but send to backend<br>
"Host: <a href="http://private.example.com" target="_blank">private.example.com</a>" and relative URI in request line.<br>
<br>
and backend will process such request as request to <a href="http://private.example.com" target="_blank">private.example.com</a><br>
<br>
because backend server see only relative uri in request line,<br>
and will use host name from Host: request header in this case.<br>
<br>
==============================<u></u>==============================<u></u>===========<br>
<br>
for proxy_pass such bug can be fixed just by using always<br>
$host instead of $http_host in proxy_set_header Host directive.<br>
<br>
for fastcgi_pass such bug can be fixed only by using two nginx<br>
servers - first for frontend, and second for backend,<br>
because nginx send to fastcgi value of $http_host<br>
<br>
bug cause:<br>
<br>
fastcgi spec was created when only HTTP/1.0 exists<br>
and don't know about absoluteURI in request line -<br>
such feature was added in HTTP/1.1, after FastCGI spec.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So, $host must be used always with proxy_pass instead of $http_host.<br>
</blockquote>
<br>
If the upstream server would do anything security-relevant with the Host:<br>
header that it gets from nginx, it would do exactly the same with the<br>
Host: header that it would get from the client directly, no?<br>
</blockquote>
<br>
No.<br>
<br>
1) <a href="http://tools.ietf.org/html/rfc7230#section-5.5" target="_blank">http://tools.ietf.org/html/<u></u>rfc7230#section-5.5</a><br>
<br>
2) <a href="http://nginx.org/en/docs/http/ngx_http_core_module.html" target="_blank">http://nginx.org/en/docs/http/<u></u>ngx_http_core_module.html</a><br>
<br>
$host<br>
    in this order of precedence: host name from the request line, or host name from the “Host” request header field, or the server name matching a request<span class="HOEnZb"><font color="#888888"><br>
<br>
-- <br>
Best regards,<br>
 Gena<br>
<br>
______________________________<u></u>_________________<br>
nginx mailing list<br>
<a href="mailto:nginx@nginx.org" target="_blank">nginx@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx" target="_blank">http://mailman.nginx.org/<u></u>mailman/listinfo/nginx</a></font></span></blockquote></div><br></div></div>