Opened 5 years ago

Closed 5 years ago

#1818 closed defect (invalid)

Custom Error Pages fails to return the correct Content-Type header in its response

Reported by: adrian.quiambao.torocloud.com@… Owned by:
Priority: blocker Milestone:
Component: nginx-module Version: 1.12.x
Keywords: Cc:
uname -a: Linux ip-10-1-200-10 4.9.119-44.140.amzn1.x86_64 #1 SMP Fri Aug 10 19:17:29 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.12.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --add-module=/datastore/temp/more_headers --with-compat --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=' -Wl,-E'

Description

Similar Issue with here: https://github.com/kubernetes/ingress-nginx/issues/4039

Background: I configured a custom error page on Nginx based on the Accept Header.

For example: curl -i https://test-nginx.text.com/api/nginxTest/502 --header 'Accept: application/json'. It would return on cli like this:

HTTP/1.1 502 Bad Gateway
Server: nginx
Date: Mon, 22 Jul 2019 00:16:13 GMT
Content-Type: application/json
Content-Length: 115
Connection: keep-alive
ETag: "5d301e25-73"
X-Content-Type-Options: nosniff

{
  "result" : "ERROR",
  "apiErrorCode" : -1,
  "message" : "Bad gateway",
  "localizedMessage" : "Bad gateway"
}

But if I didn't pass any Accept header. The default text/html should handle it. In cli, it shows the HTML error page but when I tried to access it on a browser the HTML error page would not show.

In Google Chrome v 75.0.3770.142 : It shows "ERR_INVALID_SIGNED_EXCHANGE"
In Safari v 12.1: It would download the page
In Mozilla Firefox v63.0.3: It would show the custom XML custom error page

The code should return a default content-type header text/html, but when it fails to decode the Accept header, it simply mirrors whatever came from the request into the response.

The expected behavior, in this case, is for the default backend use Content-Type: text/html when it fails to decode the Accept header.

I already tried adding the add_header X-Content-Type-Options nosniff always, but it did not fix the issue.

Snippet custom nginx config:

map $http_accept $extension {
  default html;
  ~application/json json;
  ~application/xml xml;

      more_set_headers  'Content-Type:$http_accept';
}

Change History (1)

comment:1 by Maxim Dounin, 5 years ago

Resolution: invalid
Status: newclosed

It is not clear what are you trying to do, but more_set_headers 'Content-Type:$http_accept'; is a directive of a 3rd party module which is expected to add header Content-Type to the response with $http_accept value, which is certainly wrong.

First of all, $http_accept is a variable which represents Accept header of the request. Even in valid requests this value is not guaranteed to contain something acceptable for the Content-Type header, and the configuration in question will certainly produce invalid responses.

Second, Content-Type shouldn't be added as an arbitrary header. Instead, types and default_type should be used. And if you want to provide different error pages based on the Accept request header, you can do so using variables in the error_page itself.

If you have further question on how to configure nginx, please consider support options available.

Note: See TracTickets for help on using tickets.