[转]REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR
午睡一觉醒来,突然想伪造IP地址。搜了一下,Mark。
源地址:http://www.cnblogs.com/lmule/archive/2010/10/15/1852020.html
-----------------------------------------------------------------------------------------------------------------------------------------------------------
看ecshop的lib_base.php的时候里面获取客户端真实ip的函数(real_ip),有许多情况的判断,主要判断客户端是否使用代理的情况,注意判断顺序,先判断客户端是否使用代理HTTP_X_FORWARDED_FOR
还是把源码附上吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/** * 获得用户的真实IP地址 * * @access public * @return string */ function real_ip() { static $realip = NULL; if ( $realip !== NULL) { return $realip ; } if (isset( $_SERVER )) { if (isset( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ])) { $arr = explode ( ',' , $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]); /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */ foreach ( $arr AS $ip ) { $ip = trim( $ip ); if ( $ip != 'unknown' ) { $realip = $ip ; break ; } } } elseif (isset( $_SERVER [ 'HTTP_CLIENT_IP' ])) { $realip = $_SERVER [ 'HTTP_CLIENT_IP' ]; } else { if (isset( $_SERVER [ 'REMOTE_ADDR' ])) { $realip = $_SERVER [ 'REMOTE_ADDR' ]; } else { $realip = '0.0.0.0' ; } } } else { if ( getenv ( 'HTTP_X_FORWARDED_FOR' )) { $realip = getenv ( 'HTTP_X_FORWARDED_FOR' ); } elseif ( getenv ( 'HTTP_CLIENT_IP' )) { $realip = getenv ( 'HTTP_CLIENT_IP' ); } else { $realip = getenv ( 'REMOTE_ADDR' ); } } preg_match( "/[\d\.]{7,15}/" , $realip , $onlineip ); $realip = ! empty ( $onlineip [0]) ? $onlineip [0] : '0.0.0.0' ; return $realip ; } |
顺便说下$_SERVER和getenv的区别,getenv不支持IIS的isapi方式运行的php
一、没有使用代理服务器的情况:
REMOTE_ADDR = 您的 IP
HTTP_VIA = 没数值或不显示
HTTP_X_FORWARDED_FOR = 没数值或不显示
二、使用透明代理服务器的情况:Transparent Proxies
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
这类代理服务器还是将您的信息转发给您的访问对象,无法达到隐藏真实身份的目的。
三、使用普通匿名代理服务器的情况:Anonymous Proxies
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 代理服务器 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
隐藏了您的真实IP,但是向访问对象透露了您是使用代理服务器访问他们的。
四、使用欺骗性代理服务器的情况:Distorting Proxies
REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 随机的 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
告诉了访问对象您使用了代理服务器,但编造了一个虚假的随机IP代替您的真实IP欺骗它。
五、使用高匿名代理服务器的情况:High Anonymity Proxies (Elite proxies)
REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 没数值或不显示
HTTP_X_FORWARDED_FOR = 没数值或不显示 ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
完全用代理服务器的信息替代了您的所有信息,就象您就是完全使用那台代理服务器直接访问对象。
REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。
HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是“超级匿名代理”,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。
$_SERVER['REMOTE_ADDR']; //访问端(有可能是用户,有可能是代理的)IP
$_SERVER['HTTP_CLIENT_IP']; //代理端的(有可能存在,可伪造)
$_SERVER['HTTP_X_FORWARDED_FOR']; //用户是在哪个IP使用的代理(有可能存在,也可以伪造)
----------------------------------------------------------------------------------------------------
在WEB开发中.我们可能都习惯使用下面的代码来获取客户端的IP地址:
C#代码
string IP = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(IP)) {
//没有代理IP则直接取连接客户端IP
IP = Request.ServerVariables["REMOTE_ADDR"];
}
上面代码看来起是正常的.可惜这里却隐藏了一个隐患!!因为"HTTP_X_FORWARDED_FOR"这个值是通过获取HTTP头的"X_FORWARDED_FOR"属性取得.所以这里就提供给恶意破坏者一个办法:可以伪造IP地址!!
下面是测试代码:
request.Headers.Add("X_FORWARDED_FOR", "0.0.0.0");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader stream = new StreamReader(response.GetResponseStream());
string IP = stream.ReadToEnd();
stream.Close();
response.Close();
request = null;
"ip.aspx"文件代码:
//优先取得代理IP
string IP = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(IP))
{
//没有代理IP则直接取客户端IP
IP = Request.ServerVariables["REMOTE_ADDR"];
}
Response.Write(IP);
Response.End();
这样.当测试代码中去访问ip.aspx文件时."string IP = stream.ReadToEnd();"这段代码取到的IP数据就是"0.0.0.0"!!!!(呵.在真实情况下.这样的IP地址肯定不是我们想要的结果.而在有些投票系统中限制一个IP只能投1次票时,如果也是用类似的代码取得对方IP然后再判断的话.呵呵.限制就失效咯)...
或者如果你用上面代码获取IP地址后后面又不再进行数据判断的话也许还能更进一步进行数据破坏!!
比如你用类似上面的代码中获取IP地址就直接有这样的SQL语句:
string sql = "INSERT INTO (IP) VALUE ('" + IP + "')";
那么也许破坏者还可以进行SQL注入进行数据破坏!!
这样看来利用"HTTP_X_FORWARDED_FOR"这个属性获取客户端IP的方法就不再可取了.-_-# 但如果不用这种方法.那么那些真正使用了代理服务器的人.我们又不能再获取到他们的真实IP地址(因为某些代理服务器会在"X_FORWARDED_FOR"这个HTTP头里加上访问用户真正的IP地址).呵.现实就是这样,某种东西都有有得必有失...
------------------------------------------------------------------------------------------------------
看了这两个帖子,终于明白为什么获取ip之后还要对其正则验证了,象我以前那种直接通过REMOTE_ADDR获取客户端ip,并且不对齐进行验证的想法是很傻很天真的,必须严厉打击!
[转]REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR的更多相关文章
- session的安全性
提到session,大家肯定会联想到登录,登录成功后记录登录状态,同时标记当前登录用户是谁.功能大体上就是这个样子,但是今天要讲的不是功能,而是实现.通过探讨session的实现方式来发掘一些可能你之 ...
- session的基本原理及安全性
1.session原理 提到session,大家肯定会联想到登录,登录成功后记录登录状态,同时标记当前登录用户是谁.功能大体上就是这个样子,但是今天要讲的不是功能,而是实现.通过探讨session的实 ...
- PHP获得真实客户端的真实IP REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR
REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP.如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP. HTTP_CLIENT_IP 是代理服务器发送的HTTP头. ...
- PHP获得真实客户端的真实IP REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR[]转载
REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP.如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP. HTTP_CLIENT_IP 是代理服务器发送的HTTP头. ...
- HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR、REMOTE_ADDR
REMOTE_ADDR 是你的客户端跟你的服务器"握手"时候的IP.如果使用了"匿名代理",REMOTE_ADDR将显示代理服务器的IP. HTTP_CLIEN ...
- 关于HTTP_CLIENT_IP,HTTP_X_FORWAR
HTTP_CLIENT_IP:可通过http头伪造HTTP_X_FORWARDED_FOR:可通过http头伪造REMOTE_ADDR:可能是用户真实IP也可能是代理IP 服务端获取IP地址 http ...
- HTTP 请求头中的 Remote_Addr,X-Forwarded-For,X-Real-IP
REMOTE_ADDR 表示发出请求的远程主机的 IP 地址,remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间 ...
- 获取ip
需要引用System.Web http://stackoverflow.com/questions/4879837/smart-way-to-get-the-public-internet-ip-ad ...
- php笔试题(3)--转载
1.nginx使用哪种网络协议? nginx是应用层 我觉得从下往上的话 传输层用的是tcp/ip 应用层用的是http fastcgi负责调度进程 2. <? echo 'hello tush ...
- PHP面试题三
1.nginx使用哪种网络协议? nginx是应用层 我觉得从下往上的话 传输层用的是tcp/ip 应用层用的是http fastcgi负责调度进程 2. <? echo 'hello tush ...
随机推荐
- MySQL5.7.11版本,报错Cannot proceed because system tables used by Event Scheduler were found damaged at server start
解决思路: 1. 在MySQL安装目录下执行./mysql_upgrade -uroot -p,此处是为了更新MySQL的系统表,在5.6之前的版本上,更新系统表的命令是mysql_fix_privi ...
- (转)CSS3之pointer-events(屏蔽鼠标事件)属性说明
我们在 HTML 开发时可能会遇到这样的情况:页面上有一些元素使用绝对定位布局,这些元素可能会遮盖住它们位置下方的某个元素的部分或者全部.默认情况下,下方元素被遮挡的部分是不会响应鼠标事件的. 但有时 ...
- 调试阶段 获取微信小程序openid
wx.login({ success: function(res) { //首先获取用户code //res.code wx.request({ url: 'https://api.weixin.qq ...
- docker日志清理
前言:docker运行久了,会发现它的映射磁盘空间爆满,尤其是yum安装的docker的 解决方法: 1. 用脚本清理,一般yum安装的docker,其存储空间一般都在/var/lib/docker/ ...
- 史上最简单的 SpringCloud 教程
史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)史上最简单的SpringCloud教程 | 第二篇: 服务消费者(rest+ribbon)史上最简单的Spri ...
- pycaffe简明文档
pycaffe简明文档 by ChrisZZ, imzhuo@foxmail.com 2018年01月18日19:00:56 说明 caffe的python接口没有官方说明文档,例如查看一个函数的用法 ...
- Hadoop ConnectException: Connection refused的一种解决办法
跟着视频学习天气案例,把代码敲好,准备提交运行时才发现集群没启动.然后在node02.node03.node04使用zkServer.sh start启动ZooKeeper,然后在node01使用st ...
- ElasticSearch利用IK实现全文搜索
要做到中文全文检索还需要按照中文分词库 ,这里就使用 IK来设置 安装中文分词库 相关命令: whereis elasticsearch 找到目录 进入 到/usr/elasticsearch/bin ...
- EF批量插入数据(Z.EntityFramework.Extensions)
EF用原生的插入数据方法DbSet.ADD()和 DbSet.AddRange()都很慢.所以要做大型的批量插入只能另选它法. 1.Nugget 2.代码 using EF6._0Test.EF; u ...
- Understanding about numerical stability, convergence and consistency
In a computer simulation of the real world, physical quantities, which usually have continuous distr ...