﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
2650	Uncovered edge case in host header validation	Daniil Lemenkov		"Hello to maintainers, developers and anybody interested!

I suppose there is an uncovered edge case during host header validation procedure. It is likely to be caused by a code in `ngx_http_validate_host`.

Consider the following `nginx.conf` file:
{{{
events {}

http {
    server {
        listen 8012 default_server;
        server_name _;

        return 200 ""default_server, host=$host, server_name=$server_name\n"";
    }
    server {
        listen 8012;
        server_name example.com;

        return 200 ""example.com, host=$host, server_name=$server_name\n"";
    }
    server {
        listen 8012;
        server_name example.com.;

        return 200 ""example.com. (with dot at the end), host=$host, server_name=$server_name\n"";
    }
}
}}}

... and responses of the server running the config:
{{{
$ curl localhost:8012 -H 'Host: example.com'
example.com, host=example.com, server_name=example.com

# As expected: dot-ended domains are unified
$ curl localhost:8012 -H 'Host: example.com.'
example.com, host=example.com, server_name=example.com

# Unexpected: request with dot-ended domain will not be processed in usual virtual host
$ curl localhost:8012 -H 'Host: example.com.:1234.'
example.com. (with dot at the end), host=example.com., server_name=example.com.
}}}

There are unexpected header validation results in cases when a port part of the host header contains a dot.

Although the last request is probably wrong, I suppose Nginx should provide consistent behavior in the case too to allow users to rely on it.

You may evolve these requests to a more strange one (within the same server with the same config):
{{{
# As expected: '.' is incorrect host
$ curl localhost:8012 -H 'Host: .'
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.27.0</center>
</body>
</html>

# Unexpected: the server handle and process a bad request successfully
$ curl localhost:8012 -H 'Host: .:12.34'
default_server, host=., server_name=_
}}}

In this case a request with a single-dot host header, which is forbidden usually, succeeds now.

This may have some negative impact on configurations with an authorization based on use of `$host` variable. Consider another `nginx.conf` file:
{{{
events {}

http {
    server {
        listen 8013 default_server;
        server_name _;

        root ""html/$host"";
    }
    server {
        listen 8013;
        server_name secret.example.com;

        root ""html/secret.example.com"";
        return 401 ""Unauthorized\n"";
    }
}
}}}
... and responses of the server running this config:
{{{
$ cat html/secret.example.com/secret 
SomeSecret

# As expected: an access is unauthorized
$ curl localhost:8013/secret -H 'Host: secret.example.com'
Unauthorized

# Unexpected: one may gain an unauthorized access
$ curl localhost:8013/secret.example.com/secret -H 'Host: .:.1234'
SomeSecret
}}}

Using this configuration looks like a bad approach for an authorization, nevertheless, I think the issue may cause some other unexpected cases in other applications.

I wish you consider the issue important enough to be acknowledged. To increase your interest for fixing it, I will try to prepare a patch. Hope this helps.

Thank you all a lot!"	defect	new	minor		nginx-core	1.25.x		host, patch		Linux Blue 5.19.0-46-generic #47-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 16 13:30:11 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux	"nginx version: nginx/1.27.0
built by gcc 12.2.0 (Ubuntu 12.2.0-3ubuntu1) 
configure arguments:"
