Kingthy's blog
博客园
首页
博问
闪存
新随笔
联系
订阅
管理
随笔-59 文章-0 评论-866
使用HTTP_X_FORWARDED_FOR获取客户端IP的严重后果
在WEB开发中.我们可能都习惯使用下面的代码来获取客户端的IP地址:
-----------------C#代码----------------------------------------------------------------------
//
优先取得代理IP
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地址!!
下面是测试代码:
--------------C#代码---------------------------------------------------------------------------
HttpWebRequest request
=
(HttpWebRequest)HttpWebRequest.Create(
"
http://localhost/ip.aspx
"
);
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"文件代码:
------------C#代码-----------------------------------------------------------------------------
Response.Clear();
//
优先取得代理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.即是不要再理会
代理
情况.你的建议又是怎样呢???
绿色通道:
好文要顶
关注我
收藏该文
与我联系
posted @ 2007-11-24 11:06
Kingthy
阅读(13407)
评论(29)
编辑
收藏
发表评论
2272909
回复
引用
查看
#1楼
[
楼主
]
2007-11-24 11:07
Kingthy
我的天..编辑器不见了.就成了这样的排版..汗...
回复
引用
#2楼
2007-11-24 11:11
匿名[未注册用户]
有道理。。。
回复
引用
查看
#3楼
2007-11-24 11:14
dudu
麻烦重新调整一下排版。
回复
引用
查看
#4楼
[
楼主
]
2007-11-24 11:18
Kingthy
现在好了.换了一个编辑就可以了..
"TextBox"这个编辑怎么用不了了??
回复
引用
#5楼
2007-11-24 11:24
A1[未注册用户]
呵呵,我用这个骗了不少论坛,搞了不少恶作剧,网上搜一下白宫有哪些IP,然后以此就利用工具(也可以只是浏览器插件FF下比IE容易实现)伪装成从白宫访问,哈哈哈。。。。
回到正题,个人认为还是只支持REMOTE_ADDR比较好。
至于你说的利用伪造HTTP_X_FORWARDED_FOR来实现sql注入,这个貌似02年就被爆出,某个著名的php论坛程序有此漏洞。现在多数论坛程序在处理ip地址的时候都有格式检查,即便没有,在拼接sql语句的时候肯定会过滤不安全字符的(这是最应该做的了)。
回复
引用
查看
#6楼
[
楼主
]
2007-11-24 11:31
Kingthy
@A1
嗯.认同.但现在其时还有很多WEB程序都不会处理这个IP数据的(因为在部分程序员的头脑里IP地址就是XXX.XXX.XXX.XXX.所以认为是数据安全的). :0
回复
引用
查看
#7楼
2007-11-24 12:02
阿不
还是拼接SQL的错误。
回复
引用
#8楼
2007-11-24 13:01
banroo[未注册用户]
老漏洞了。
做好过滤是应该的。
回复
引用
查看
#9楼
2007-11-24 13:44
曲滨*銘龘鶽
Http Header 本来就是方便传输一些数据的
根本就没有加密
这一点作Web的人应该心知肚明。
回复
引用
查看
#10楼
2007-11-24 17:15
Enzo
@A1
恩,现在都要过滤输入字符!
回复
引用
查看
#11楼
2007-11-24 20:05
zoti
有道理,顶一个。
回复
引用
#12楼
2007-11-24 22:01
禾口王(只是没登录)[未注册用户]
推荐阅读HTTP协议
回复
引用
查看
#13楼
2007-11-25 02:30
米开朗基罗
http的头本来就是不可信的,要把它和用户从textbox里面输入的字符串作同等处理。
可以把HTTP_X_FORWARDED_FOR作为一个判断逻辑里面的参考,比较一下看里面是不是已经有了。
其实,限制一个ip只能投一票,它就影响了很多NAT方式共用一个ip的人的正常使用。影响小的是一个家里的人,比如大姐一台电脑,你的一台电脑。两个人,但你们只能投一票。影响大点就是有些垃圾isp,装网的时候就给你一个10.x.x.x,然后让你到它的内部网关路由出去,一堆人用一个ip。
回复
引用
查看
#14楼
2007-11-25 09:00
暗香浮动
那ip如何获取才是可信的呢。
回复
引用
#15楼
2007-11-25 11:57
5555[未注册用户]
public static string GetRealIP()
{
string ip;
try
{
if (HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
{
ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim();
}
else
{
ip = HttpContext.Current.Request.UserHostAddress;
}
}
catch (Exception e)
{
throw e;
}
return ip;
}
用上面的函数获取IP
回复
引用
查看
#16楼
2007-11-25 13:42
米开朗基罗
@5555
楼上的一行写太多代码了:
ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim();
回复
引用
查看
#17楼
[
楼主
]
2007-11-25 21:05
Kingthy
@米开朗基罗
HTTP头这肯定是不可信的.
@暗香浮动
只有"Request.UserHostAddress"才是可信的.但是这样的话却又获取不了那些已使用了代理服务器的用户真实IP地址(因为在这时Request.UserHostAddress获取到的就是这代理服务器的IP)..
回复
引用
#18楼
2007-11-25 22:16
helixapp[未注册用户]
这个看怎么选择了 一般的情况下 特别是使用IE 伪造这个头的可能比较小
假如不判断这个头,作弊者想要找一堆的代理 也不难啊
回复
引用
查看
#19楼
2007-11-26 00:47
米开朗基罗
@Kingthy
在大众化的产品里面想identify一个用户就是和用户的隐私作搏斗,技术上有很多反追踪的办法的,所以不能完全做到你想要的效果,只可以尽量去堵漏洞,并消除带来的影响。
回复
引用
#20楼
2007-11-26 16:50
cozo[未注册用户]
有时候我的程序需要隐藏在自己的Apache的Proxy模块后面,这样如果不用这个方法,取到的IP全部是127.0.0.1。
回复
引用
查看
#21楼
[
楼主
]
2007-11-28 22:48
Kingthy
@cozo
因为你已经知道你的程序是要经过你自己的Proxy,所以基本就可以相信那些数据了..
回复
引用
#22楼
2007-11-30 16:04
郁闷,怎么提示这个[未注册用户]
对了,好像用ASP不行.试一下下面的代码
<%
userip = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
If userip = "" Then userip = Request.ServerVariables("REMOTE_ADDR")
Response.write(userip)
%>
<table>
<% For Each sd In Request.ServerVariables %>
<TR><TD> <%= sd%> </TD>
<TD> <%= Request.ServerVariables(sd) %> </TD>
</TR>
<% Next %>
</table>
回复
引用
#23楼
2008-10-14 23:49
fearwall[未注册用户]
public long IPtoNum(string Ip)
{
string[] stringip = new string[4];
stringip = Ip.Split('.');
long ipnum = Convert.ToInt64((stringip[0])) * 16777216 + Convert.ToInt64(stringip[1]) * 65536 + Convert.ToInt64(stringip[2])*256 + Convert.ToInt64(stringip[3]);
return ipnum;
}
回复
引用
#24楼
2009-03-21 09:06
阿嫂法司fasfasf[未注册用户]
sadf
回复
引用
#25楼
2009-03-21 09:06
阿嫂法司fasfasf[未注册用户]
sfasdf
回复
引用
查看
#26楼
2009-11-08 08:15
rym1020
如果是用了squid进行加速的网站那如何对待这个问题呢?如果不取代理IP,那全是服务器的IP了。如果取代理IP,那么又可以伪造。。。不知道腾讯、新浪等网站是如何处理的?
回复
引用
查看
#27楼
2011-02-19 15:24
betsell
介绍说明:
相信很多做过“皇冠投注系统出租或安装”的技术人员来说,会有一个很头痛的技术问题:那就是客户要求经常要求更换服务器(至少更换IP)。
大部分情况都是直接把程序安装到新的服务器去,当然也包括导入和导出数据库等一系列工作。要是新服务器的配置环境遇到什么问题的话,恐怕需要花不长时间调试。
使用说明:
影射规则例子:源127.0.0.1,目标127.0.0.1:8080;则当浏览器访问127.0.0.1的时候会和直接访问127.0.0.1:8080的感觉一样;依照这样的方法也可以保留服务器本身的www服务,只需要把www服务的端口改成其他端口(如8080),接着按上边方法添加目标规则就可以了。也可以直接修改map.txt(这个是影射规则文件)的写字板文件。
免责申请:
由于本软件免费,所以不提供任何保证,也不包括所有因为本软件带来的法律风险,请使用者不要违反当地的法律法规。
PS:服务端程序可以调用http头里边的“X_FORWARDED_FOR”信息,这个是访问者的真实IP;
运行需求:.NET Framework 3.5
文章来源:<a href="http://www.betsell.net" target="_blank">betsell</a>
回复
引用
查看
#28楼
2011-12-18 15:00
杨印
你们说的这些代码,我都试过了,全都获得不了我的真是IP
注册用户登录后才能发表评论,请
登录
或
注册
,
返回博客园首页
。
首页
博问
闪存
新闻
园子
招聘
知识库
最新IT新闻
:
·
亚马逊选举格雷里克为董事会成员
·
完美世界近期业务进展:推出《赤壁》资料片
·
分析称马云决定阿里巴巴与雅虎交易成败
·
京东商城注册用户达3000万 日均订单处理量超30万
·
开心网否认无线业务裁员:仅为划分至各部门
»
更多新闻...
最新知识库文章
:
·
高级编程语言的发展历程
·
如何学习一门新的编程语言?
·
学习不同编程语言的重要性
·
为什么我喜欢富于表达性的编程语言
·
计算机专业的女生为什么要学编程
»
更多知识库文章...
China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务
公告
本人博客文章,如果不加以说明则为
本人原创
!如果各位需要转载,请注明原作者及出处!谢谢!!
昵称:
Kingthy
园龄:
4年5个月
粉丝:
61
关注:
2
<
2007年11月
>
日
一
二
三
四
五
六
28
29
30
31
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
1
2
3
4
5
6
7
8
搜索
常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
我的标签
KT
(9)
vtemplate
(8)
模版引擎
(4)
Linq
(3)
验证码识别
(2)
文件同步精灵
(2)
Flex
(1)
Socket5
(1)
RegexTest
(1)
Template
(1)
更多
随笔分类
C#(50)
(rss)
Sql(1)
(rss)
Web(6)
(rss)
其它(8)
(rss)
随笔档案
2011年9月 (2)
2011年8月 (9)
2011年3月 (1)
2010年12月 (1)
2010年3月 (1)
2009年12月 (4)
2009年10月 (2)
2009年9月 (2)
2009年8月 (3)
2009年7月 (1)
2009年6月 (1)
2009年3月 (3)
2008年11月 (1)
2008年10月 (2)
2008年9月 (2)
2008年8月 (3)
2008年6月 (2)
2008年5月 (3)
2008年4月 (6)
2008年3月 (1)
2008年1月 (1)
2007年12月 (2)
2007年11月 (1)
2007年10月 (1)
2007年9月 (4)
最新评论
阅读排行榜
评论排行榜
推荐排行榜