#629 closed defect (invalid)
Nginx as a reverse proxy will not pass headers that contain a period.
Reported by: | Cameron Ortiz | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | |
Component: | nginx-core | Version: | 1.6.x |
Keywords: | Cc: | ||
uname -a: |
[root@cloud-server-01 ~]# uname -a
Linux cloud-server-01 2.6.32-431.29.2.el6.x86_64 #1 SMP Tue Sep 9 21:36:05 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux |
||
nginx -V: |
[root@cloud-server-01 ~]# nginx -V
nginx version: nginx/1.6.2 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --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/nginx.pid --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-http_ssl_module --with-http_realip_module --with-http_addition_module --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_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' |
Description
When Nginx is configured as a reverse proxy it will not pass any http headers that have a name containing a period.
I was able to reproduce this issue by creating a very basic reverse proxy configuration in nginx to another server running apache:
[root@cloud-server-01 ~]# cat /etc/nginx/conf.d/headertest.conf server { listen 166.78.134.122:80; location / { proxy_pass http://10.183.5.144; } }
On the Apache server I created a small php script that would show the request headers:
[root@cloud-server-02 ~]# cat /var/www/html/index.php <?php $headers = apache_request_headers(); foreach ($headers as $header => $value) { echo "$header: $value <br />\n"; } ?>
When I pass a header that has a period to the NginX server it does not get forwarded to the Apache server:
[ccortiz@ninja ~]$ curl -H 'test: this is a test' 166.78.134.122 Host: 10.183.5.144 <br /> Connection: close <br /> User-Agent: curl/7.32.0 <br /> Accept: */* <br /> test: this is a test <br /> Via: 1.1 537618-AUS2WWSG01.secops.rackspace.com 0A014411 <br /> [ccortiz@ninja ~]$ curl -H 'tes.t: this is a test' 166.78.134.122 Host: 10.183.5.144 <br /> Connection: close <br /> User-Agent: curl/7.32.0 <br /> Accept: */* <br /> Via: 1.1 537618-AUS2WWSG01.secops.rackspace.com 0A014411 <br />
I have attached a tcpdump that was ran on the nginx server. You can view this in wireshark to see that the header is coming into nginx but is not going out to the apache server.
Attachments (1)
Change History (6)
by , 10 years ago
Attachment: | tcpdump.pcap added |
---|
comment:1 by , 10 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 9 years ago
(I'm not the original submitter)
I'm asking for this to be reopened because the option ignore_invalid_headers
actually ignores headers which are valid. A period is a valid header field. Per RFC 2730 (HTTP 1.1 Message Syntax and Routing) (http://tools.ietf.org/html/rfc7230) we have:
- 3.2: header-field = field-name ":" OWS field-value OWS
- 3.2: field-name = token
- 3.2.6: token = 1*tchar
- 3.2.6: tchar = "
!
" / "#
" / "$
" / "%
" / "&
" / "'
" / "*
" / "+
" / "-
" / ".
" / "^
" / "_
" / "(backquote)" / "|
" / "~
" / DIGIT / ALPHA
comment:3 by , 9 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
comment:4 by , 9 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
By default nginx ignores headers it considers invalid as per rules documented. The rules are composed based on what various standards define, what real browsers use, and the fact that other characters may be unsafe with various commonly used software, including nginx itself. Whether or not these headers match a grammar of a particular RFC is mostly irrelevant. The ignore_invalid_headers
directive allows to control whether only headers matching the rules documented will be handled and passed to upstream servers by nginx, or any header will do.
There are no plans to change the default behaviour. If you disagree with the directive name - you may suggest renaming it. If you want to introduce some additional behaviour, e.g., to pass headers with dots, you may introduce an additional directive to do this, similar to underscores_in_headers
. In either case please make it clear why the suggested change is needed. See Contributing Changes for some additional details.
http://nginx.org/r/ignore_invalid_headers