Edit report at https://bugs.php.net/bug.php?id=64457&edit=1
ID: 64457 Comment by: d...@php.net Reported by: d...@php.net Summary: HTTP_HOST, SERVER_NAME, SERVER_PORT spoofing Status: Analyzed Type: Bug Package: Apache2 related Operating System: All PHP Version: Irrelevant Block user comment: N Private report: N New Comment: With the help of thumbs from #httpd, I was directed to: http://httpd.apache.org/docs/current/mod/core.html#usecanonicalphysicalport It was pointed out: http://httpd.apache.org/docs/2.4/mod/core.html#comment_1000 So, PHP is kept in the dark if these directives are Off. On our side, docs should be updated to advise that values are not be trusted if aforementioned directives are Off. Previous Comments: ------------------------------------------------------------------------ [2013-03-19 20:58:07] ras...@php.net I have no idea why it is filling in the wrong SERVER_PORT, but it is. This doesn't come from PHP and it isn't PHP's job to second-guess what the web server is telling us here. Try to reproduce it with a straight CGI script without any PHP involvement. ------------------------------------------------------------------------ [2013-03-19 19:38:43] d...@php.net Indeed, it's not a PHP issue per se, and I'm glad, thank you. I'm aware that $_SERVER['HTTP_*'] are passed on, but what about $_SERVER['SERVER_*'] (or you meant everything web server related)? Why would Apache not know what is the hostname and which port is it serving through? Nginx and some variations of Apache (haven't tried sending HTTP 1.0 request) settings don't have this "problem". RFC 2616 states that 1.1 requests specifying a hostname not in use by the server should receive a 400 Bad Request response, which is sometimes (I don't know when exactly) is not the case. Thanks. ------------------------------------------------------------------------ [2013-03-19 19:16:48] ras...@php.net But how is this a PHP issue? PHP doesn't set the $_SERVER['HTTP_*"] variables at all. They are inherited directly from the web server and are the same variables that the web server would set for CGI scripts that might get executed. So while we could try to do some analysis and filtering at the PHP level, anything else the web server invokes would still be getting the spoofed port. The fix should be at the web server level. ------------------------------------------------------------------------ [2013-03-19 19:03:42] d...@php.net Description: ------------ `HTTP_HOST` is the value from `Host` header, which can, naturally, be spoofed. On the other hand, `SERVER_NAME` and `SERVER_PORT` should reflect real values. I've tested some configurations and on majority you can at least change/spoof `SERVER_PORT`. This can lead to security issues since these environment variables are often trusted. Test script: --------------- <?php $ch = curl_init('http://smchiptuning.com/http_host.php'); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: 127.0.0.1:1337')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); echo curl_exec($ch); curl_close($ch); /** http_host.php <?php var_dump($_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT']); */ Expected result: ---------------- string(16) "smchiptuning.com" string(2) "80" Actual result: -------------- string(9) "127.0.0.1" string(4) "1337" ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=64457&edit=1