I have a debian 8 VPS running with nginx 1.10.3.
I host several Symfony 3.2 websites (using php7-fpm), and I face headers injection problems. I can't figure out if the problem is more from nginx or from the symfony project configuration.
I am not using any LoadBalancer like Varnish or Amazon AWS for now.
When someone sends a request using an invalid X-Forwared-Host
such as :
X-Forwarded-Host: pg_sleep(2)
Then it receives a 500 Internal Server Error
, and I can see a critical error in the logs:
UnexpectedValueException: "Invalid Host "pg_sleep(2)" at [...]/var/bootstrap.php.cache"
I can easily reproduce it (only on production environment, using this bootstrap.php.cache file) with curl :
curl -I\
-H "X-Forwarded-Host: pg_sleep(2)"\
"https://my-domain.tld"
Some other values I got can be X-Forwarded-Host: *.domain.tld
, X-Forwarded-Host: -1 or 2+429-429-1=0+0+0+1 --
, X-Forwarded-Host: -1; waitfor delay '0:0:14' --
etc.
I looks like an injection attack.
My goal is to handle such invalid headers and return for instance a 444 status, or at least prevent the application to trigger 500 Internal Server Error
.
My first question is : should I try to intercept such unvalid headers inside nginx configuration (using a module ?) or is it something that should be handled by the symfony project instead ?
I have read this guide : http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html
You should also make sure that your proxy filters unauthorized use of these headers, e.g. if a proxy natively uses the X-Forwarded-For header, it should not allow clients to send Forwarded headers to Symfony.
Which makes me think this should by handled by nginx, then... How?
I have tried to check the host inside my server{} block, but it doesn't intercept it...
server {
listen 443;
# [...]
if ($host !~ ^(my-domain.tld)$ ) {
return 444;
}
# [...]
}
I looks like it could be possible to use the headers_more
module, but is it the best practice?