Do not trust the data coming from the client.Almost all of this rule is well known and respected. We pass form validators through cookies, even URIs.
HTTP_HOST and SERVER_NAME .$_SERVER['HTTP_HOST'] . At a quick scan, I found quite a few cases where the data that came in this variable were left without filtering. Most often, only the existence of $_SERVER['HTTP_HOST'] , but they are not validated. GET / HTTP/1.1 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.3 Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cache-Control:max-age=0 Connection:keep-alive Host:site.dev Referer:http://site.dev/index.htm User-Agent:TelnetTest HTTP_HOST ) Host:site.dev, then the server will return 400 Bad Request GET http://site.dev/ HTTP/1.1 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.3 Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cache-Control:max-age=0 Connection:keep-alive Host:site.dev Referer:http://site.dev/index.htm User-Agent:TelnetTest GET / HTTP/1.1 GET http://site.dev/ HTTP/1.1 but GET http://site.dev/ Then all subsequent headers will be discarded, Nginx will work out the server section defined for server_name site.dev; But HTTP_HOST and SERVER_NAME will not be determined.HTTP_HOST an empty HTTP_HOST fails: Host: But it turns out to pass Host:_ or Host:"" $ telnet site.dev 80 Trying 127.0.0.1... Connected to site.dev. Escape character is '^]'. GET http://site.dev/phpinfo.php HTTP/1.1 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.3 Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cache-Control:max-age=0 Connection:keep-alive Host:~%#$^&*()<>?@\!."'{}[]=+| Referer:http://site.dev/index.htm User-Agent:TelnetTest _SERVER["SERVER_NAME"]: ~%#$^&*()<>?@\!."'{}[]=+| _SERVER["HTTP_HOST"]: ~%#$^&*()<>?@\!."'{}[]=+| HTTP/1.1 200 OK Server: nginx/1.0.10 Date: Wed, 23 Jan 2013 10:31:14 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive '/' in the Host: header, the server will return 400 Bad Request .Host:../../ header will not work, such Host:http://evil.site too $allowed_hosts = array('foo.example.com', 'bar.example.com'); if (!isset($_SERVER['HTTP_HOST']) || !in_array($_SERVER['HTTP_HOST'], $allowed_hosts)) { header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request'); exit; } HTTP_HOST on the web server side.HTTP_HOST add the following lines to Nginx's config: fastcgi_param HTTP_HOST1 $http_host; fastcgi_param HTTP_HOST2 $host; fastcgi_param HTTP_HOST3 $server_name; server sections defined: server { listen 80; server_name site1.dev; ... } server { listen 80; server_name site2.dev site3.dev; ... } $ telnet site1.dev 80 Trying 127.0.0.1... Connected to site.dev. Escape character is '^]'. GET http://site3.dev/phpinfo.php HTTP/1.1 Host:~%#$^&*()<>?@\!."'{}[]=+| User-Agent:TelnetTest _SERVER["HTTP_HOST1"]: ~%#$^&*()<>?@\!."'{}[]=+| _SERVER["HTTP_HOST2"]: site3.dev _SERVER["HTTP_HOST3"]: site2.dev fastcgi_param HTTP_HOST $host; $ telnet site3.dev 80 GET /phpinfo.php HTTP/1.1 Host:~%#$^&*()<>?@\!."'{}[]=+| User-Agent:TelnetTest server { listen 80 default_server; server_name ""; return 444; } Source: https://habr.com/ru/post/166855/
All Articles