4

I'm using nginx as TLS terminator in front of an Apache 2.4 server.

I'm using add_header X-Content-Type-Options nosniff; in nginx to add this header to every response.

If the HTTP status code returned by Apache is below 400 the header is correctly set, but if the status is greater or equal 400 the header is omitted.

Same for the gzip module. If the status code is below 500, the gzip module automatically compresses the response body. But if the HTTP status code geturned by Apache is greater or equal 500 the gzip module just does nothing.

Some relevant parts of my nginx config:

proxy_intercept_errors    off;
proxy_ignore_client_abort off;
proxy_http_version        1.1;
proxy_hide_header         X-Powered-By;
proxy_set_header          Connection  "";     #for keepalive to backend
add_header X-Content-Type-Options nosniff;

### gzip ###
gzip on;
gzip_min_length 20;     #default: 20
gzip_comp_level 9;
gzip_proxied any;
gzip_vary on;
gzip_types *;
gunzip on;

Is there anything I can do to deactivate this behaviour and add my header to HTTP error responses and even gzip HTTP 500 responses?

Thilo
  • 243
  • 3
  • 11
  • Please edit your question to include your entire Nginx and server block config as it's likely relevant. – Tim May 29 '17 at 01:56
  • @Tim I added my whole server config as requested. Hope this helps. – Thilo May 29 '17 at 22:02
  • Thanks, I wanted to see if you were doing something odd. Looks pretty standard. Do other headers get added in the error section? What problem is this causing, or is it a theoretical question? Regarding gzip I'm going to guess (complete guess) that something in the Nginx code tells Nginx not to bother compressing pages with an error status - errors should be rare enough that it makes little difference. Is it causing a problem? – Tim May 30 '17 at 02:13
  • Well, regarding gzip: that's not a real problem, but it would be nice if error pages delivered by the backend would get compressed, too. That would just be consistent imho...regarding the headers: no, only the headers shown in the config (Strict-Transport-Security and X-Content-Type-Options) are added. But both are missing on pages >=400. And that's a real problem (security wise). The error page delivered by the backend is /temporary_error.php by the way. – Thilo May 30 '17 at 02:36
  • @Tim Please see my last comment – Thilo Jun 04 '17 at 19:24
  • HSTS doesn't have to be on every page, so that's not a problem. Likewise nosniff isn't likely to be a problem on an error page. So I can't see that there's actually a problem. If there is it's beyond my knowledge to help sorry, I think you'll have to start digging into the Nginx source code – Tim Jun 04 '17 at 19:56

1 Answers1

5

Today I stumbled upon the solution in an ssl labs thread over here: https://community.qualys.com/thread/17333-hsts-header-not-being-set-by-nginx-on-error

Basically you have to add the always keyword in the add_header config option. Quoting the nginx docs (http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header):

If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.

This helps and now every response (including the errors) have all headers set as expected.

Thilo
  • 243
  • 3
  • 11