我有一个简单的脚本来确定用户的IP地址:
function GetIp(){
if (!empty($_SERVER['HTTP_CLIENT_IP']))
//check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
//to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
现在在网上我看到有人使用这个脚本:
if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '')
$Ip = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '')
$Ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '')
$Ip = $_SERVER['REMOTE_ADDR'];
我想知道我的实现是否已损坏..我是否需要检查$_SERVER['HTTP_CLIENT_IP']
,$_SERVER['HTTP_X_FORWARDED_FOR']
或$_SERVER['REMOTE_ADDR']
的值是否为空?或者实际上没必要这样做?
答案 0 :(得分:14)
如果你想找出客户端的IP地址的原因非常重要,那就搞砸了所有这些。
这些标头值中的任何一个都可以自由欺骗。
REMOTE_ADDR
是唯一真正可靠的信息,因为它是由处理请求的Web服务器传输给您的。它理论上可以是falsified as well,但这比欺骗标题值要困难得多,而且是一种完全不同的攻击类别。
在反向代理背后的非常非常具体的托管环境中有例外。在这些情况下,管理该代理的人将能够告诉您需要测试哪个标头值。
答案 1 :(得分:8)
来自Kohanas的请求类:
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
// Format: "X-Forwarded-For: client1, proxy1, proxy2"
$client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['HTTP_CLIENT_IP'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
$client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['REMOTE_ADDR']))
{
// The remote IP address
Request::$client_ip = $_SERVER['REMOTE_ADDR'];
}
这非常好。在这种情况下,请注意Request::$trusted_proxies
数组以及$ip
var为Request::$client_ip
。
答案 2 :(得分:7)
除非您明确知道您的应用程序是在反向代理后面配置的,否则请勿检查客户端IP的任何HTTP_*
标头。无条件地信任这些标头的值将允许用户欺骗他们的IP地址。
包含可靠值的唯一$_SERVER
字段为REMOTE_ADDR
。
答案 3 :(得分:1)
这两件事实际上是相同的。在你发现的脚本中,作者只是检查数组中的元素是否在检查它是非空的之前是否已设置。
关于使用empty()
- 函数而不是比较,请检查http://php.net/empty。由于您正在处理由环境而不是用户输入设置的变量,因此您选择的两个选项中的哪一个无关紧要。所以你的脚本应该是完美的