﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
1092	virtal host attacks: Limit Host header to CN/DNS-Name of currently used certificate	Darkudorus@…		"I have read https://bh.ht.vc/vhost_confusion.pdf (read it, it's enlightening!)
and seen the first image here: https://twitter.com/com/status/781521581575135232
But Error 1013 ""HTTP hostname and TLS SNI hostname mismatch"" don't come in my personal tests with domains on cloudflare.

------
My test (with a normal nginx mainline server):
'''sni-evil.tld''' has
echo ""Server Name: $server_name<br>\nHTTP_Host: $http_host<br>\nHost: $host<br>\nSSL_server_name: $ssl_server_name"";

sni-website.tld is not modified.

Both are on hostname.tld (default_server).

With https://addons.mozilla.org/firefox/addon/modify-headers/ I changed the Host header to ""Host: '''sni-evil.tld'''"" while I am on sni-website.tld.
----
== From Screenshot 1: ==
Browser location bar: https://sni-website.tld
> Server Name: '''sni-evil.tld'''
> HTTP_Host: '''sni-evil.tld'''
> Host: '''sni-evil.tld'''
> SSL_server_name: sni-website.tld

Notice: You don't see the original content from sni-website.tld here, this is from the echo of sni-evil.tld, because the Host header is modified.
'''But sni-evil.tld would get all cookies from sni-website.tld.'''

I am no expert in this. But the webserver should only deliver the content of the address in the location bar of the browser.

Another possible bug: Think also of a session-resumption with a certificate  ""localhost, www.facebook.com"". It might be applicable here (read the PDF from the first sentence).

----

then I changed the address in the location bar to '''www.'''sni-website.tld and pressed F5

----
== From Screenshot 2: ==
Browser location bar: https://www.sni-website.tld
> Server Name: '''sni-evil.tld'''
> HTTP_Host: '''sni-evil.tld'''
> Host: '''sni-evil.tld'''
> SSL_server_name: sni-website.tld
----

Because the certificate includes both domains (with and without www), the current tls session and $ssl_server_name are not changed (to the real used SNI domain).
$ssl_server_name only changes if I press Strg + F5 (in Firefox):
----
== From Screenshot 3: ==
Browser location bar: https://www.sni-website.tld
> Server Name: '''sni-evil.tld'''
> HTTP_Host: '''sni-evil.tld'''
> Host: '''sni-evil.tld'''
> SSL_server_name: www.sni-website.tld
----

So you see ""if ($ssl_server_name != $http_host) { return 400; }"" would not work as fix here.

This problem has the whole web.

You can go to https://nofap.nl (hosted on Cloudflare) and Modify the Host header to ""Host: getbootstrap.com"" (both are in the same certificate), and you will see the whole getbootstrap.com website under nofap.nl, where it doesn't belong to.
----
The host header could be modified in the browser by an addon, ""security"" software, malware etc.
To assign an exclusive IPv6 address for each certificate can't be se solution because SNI would be dead then.
----
'''Proposed fix for this:'''
Because one certificate with multiple DNS-Names could be used in multiple server-blocks, it would be enough to check,
* if the current ""Host"" header is one of the domains in CN/DNS-Names in the certificate of the current tls session
and
* when the Host header includes a Port, then it have to be a Port (in one of ""listen"") of the server block nginx wants to use.

Otherwise return Error 400 Bad Request.
"	defect	closed	major	1.11.5	nginx-core	1.11.x	invalid			Ubuntu 16.04 # Linux hostname.tld 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 	https://launchpad.net/~nginx/+archive/ubuntu/development # nginx version: nginx/1.11.3 built with OpenSSL 1.0.2g-fips 1 Mar 2016 (running with OpenSSL 1.0.2g 1 Mar 2016) TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_mp4_module --with-http_perl_module --with-http_random_index_module --with-http_secure_link_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-stream --with-stream_ssl_module --with-threads --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/headers-more-nginx-module --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-auth-pam --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-cache-purge --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-dav-ext-module --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-development-kit --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-echo --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/ngx-fancyindex --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-http-push --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-lua --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-upload-progress --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/nginx-upstream-fair --add-module=/build/nginx-arw1Xp/nginx-1.11.3/debian/modules/ngx_http_substitutions_filter_module 
