Opened 7 months ago

Last modified 7 months ago

#2258 new enhancement

add_header directive: A colon added after the header name passes Nginx syntax validation and breaks the website once applied

Reported by:… Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.18.x
Keywords: add_header Cc:…
uname -a: Linux proxy-test1.proxy 3.10.0-1127.13.1.el7.x86_64 #1 SMP Tue Jun 23 15:46:38 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (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 --pid-path=/var/run/ --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'


This morning, I added the following directive to one of my proxy configurations, without noticing the colon (:) character produced by the Permissions-Policy generator I did use.

	"accelerometer=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(self), eexecution-while-not-rendered=(self), execution-while-out-of-viewport=(self), fullscreen=(self), geolocation=(self), gyroscope=(), magnetometer=(), navigation-override=(self), payment=(), screen-wake-lock=(self), sync-xhr=(self), usb=(), web-share=(self), clipboard-read=(self), clipboard-write=(self), idle-detection=(self)"

As always, I verified the NGINX configuration before applying it, nginx -t reporting no issues. Then I have applied it, with no issues. Afterwards, the website was reported to be unavailable (Chrome reporting a ERR_HTTP2_PROTOCOL_ERROR error and cURL reporting "curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)").

I finally managed to find the culprit (the colon) and restore website availability.

The incorrectly positioned colon should make the syntax validation fail.

Change History (1)

comment:1 by Maxim Dounin, 7 months ago

Priority: majorminor
Type: defectenhancement

The add_header directive is a low-level directive which makes it possible to return any headers, including ones which are invalid in some protocol versions and rejected by some clients (and even nginx itself). It should be used with care. Note well that there is more than one way to break things by incorrectly using the add_header directive: for example, in #691 the directive was used to return duplicate Content-Type header, with the similar results.

On the other hand, extra colon seems to be a common configuration error, see at least #1409, and it may make sense to address this somehow. Not sure how to preserve the ability to actually return such invalid headers though.

Note: See TracTickets for help on using tickets.