Is $http_host dangerous?

Francis Daly francis at
Sun May 27 23:21:07 UTC 2012

On Sun, May 27, 2012 at 05:56:23PM -0400, x7311 wrote:

Hi there,

> When the HOST is empty, it's responded with 400 as expected. 

Yes, that's the expected response for HTTP/1.1.

But add a "-0" curl argument to make it use HTTP/1.0, and nginx should
allow the request through for your application to process.

> I think the argument would come down to whether we trust the value sent
> by the user.

The short answer is "never trust the value sent by the user" ;-)

I think it comes down to how you use the user-provided value, and what
you are protecting against.

> In both use of $http_host and $host, I think the 3rd curl command is
> trying to send a custom header whose HOST value is user-defined?

Yes. Strictly, *every* header has user-defined content, always. nginx
does do some validation on the content of Host: to catch some
obviously-malformed names, but it cannot catch all. $server_name is
fully under your control, so it may be appropriate to use that instead.

> I
> believe that if we compromised the DNS or the network for example, there
> is a possible way to hijack the nginx servers by modifying the
> header....

What do you mean by "hijack"?

And what problem are you trying to protect against?

If you echo back the Host: header you get in a Location: header, the
client may have difficulty following the redirection. That probably
isn't for you to be worried about.

If you echo back the Host: header within html, then the client may treat
it as trusted-from-you, which would be bad. That probably is something
for you to avoid.

If you directly *use* the Host: header contents to determine which
internal resource to return, then you may end up revealing something
that you didn't intend to. Or accessing an external server that you
didn't intend to. That is certainly something for you to avoid.

> Since $host is a strict version of $http_host, and when it's empty it
> uses $server_name directive, I believe it's a small bit of extra
> security layer.... besides gettin rid off the port number in the
> response?

Different variables, different uses. Possibly a completely different
variable would be useful, which could be "the host:port to include in
any redirection which the client can be expected to be able to use to
get to this server". I'm not sure if that exists yet.

(I'm also not sure if it would be immediately useful outside of testing
or unusual port-forwarding scenarios that are already likely not working

Francis Daly        francis at

More information about the nginx mailing list