Created
June 29, 2019 14:22
-
-
Save FerraBraiZ/1d81f79bb2aaf80e80d246884f1c306a to your computer and use it in GitHub Desktop.
HTTP_X_FORWARDED_FOR properly done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
In the light of the latest httpoxy (https://httpoxy.org/) vulnerabilities, | |
there is really a need for a full example, how to use HTTP_X_FORWARDED_FOR properly. | |
So here is an example written in PHP, how to detect a client IP address, if you know | |
that client may be behind a proxy and you know this proxy can be trusted. | |
If you don't known any trusted proxies, just use REMOTE_ADDR | |
*/ | |
function get_client_ip () | |
{ | |
// Nothing to do without any reliable information | |
if (!isset ($_SERVER['REMOTE_ADDR'])) { | |
return NULL; | |
} | |
// Header that is used by the trusted proxy to refer to | |
// the original IP | |
$proxy_header = "HTTP_X_FORWARDED_FOR"; | |
// List of all the proxies that are known to handle 'proxy_header' | |
// in known, safe manner | |
$trusted_proxies = array ("2001:db8::1", "192.168.50.1"); | |
if (in_array ($_SERVER['REMOTE_ADDR'], $trusted_proxies)) { | |
// Get the IP address of the client behind trusted proxy | |
if (array_key_exists ($proxy_header, $_SERVER)) { | |
// Header can contain multiple IP-s of proxies that are passed through. | |
// Only the IP added by the last proxy (last IP in the list) can be trusted. | |
$proxy_list = explode (",", $_SERVER[$proxy_header]); | |
$client_ip = trim (end ($proxy_list)); | |
// Validate just in case | |
if (filter_var ($client_ip, FILTER_VALIDATE_IP)) { | |
return $client_ip; | |
} else { | |
// Validation failed - beat the guy who configured the proxy or | |
// the guy who created the trusted proxy list? | |
// TODO: some error handling to notify about the need of punishment | |
} | |
} | |
} | |
// In all other cases, REMOTE_ADDR is the ONLY IP we can trust. | |
return $_SERVER['REMOTE_ADDR']; | |
} | |
print get_client_ip (); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment