Opened 5 years ago

Closed 4 years ago

#629 closed defect (invalid)

Nginx as a reverse proxy will not pass headers that contain a period.

Reported by: cameronortiz34@… 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)

tcpdump.pcap (4.6 KB) - added by cameronortiz34@… 5 years ago.

Download all attachments as: .zip

Change History (5)

Changed 5 years ago by cameronortiz34@…

comment:1 Changed 5 years ago by vbart

  • Resolution set to invalid
  • Status changed from new to closed

comment:2 Changed 4 years ago by efge@…

(I'm not the original submitter)

I'm asking for this to be reopened because the default behavior 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
Last edited 4 years ago by efge@… (previous) (diff)

comment:3 Changed 4 years ago by efge@…

  • Resolution invalid deleted
  • Status changed from closed to reopened

comment:4 Changed 4 years ago by mdounin

  • Resolution set to invalid
  • Status changed from reopened to 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.

Note: See TracTickets for help on using tickets.