Kingthy's blog
博客园
社区
首页
新随笔
联系
管理
订阅
随笔- 40 文章- 0 评论- 382
使用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
阅读(6142)
评论(26)
编辑
收藏
网摘
所属分类:
Web
发表评论
回复
引用
查看
#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
刷新评论
切换模板
发表评论
昵称:
[登录]
[注册]
主页:
邮箱:
(仅博主可见)
验证码:
看不清,换一个
评论内容:
登录
注册
[使用Ctrl+Enter键快速提交评论]
0
970783
导航:
网站首页
社区
新闻
博问
闪存
网摘
招聘
找找看
Google搜索
China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务
相关文章:
最新IT新闻:
19岁天才黑客发布首个iPhone 3GS破解软件
新浪邮箱大本营粉墨登场!Sina.cn开放注册
IE市场份额首次跌破60%
Google App Engine宕机6小时——云的安全在哪里?
微软新推社交网站Windows Live Planet
相关链接:
公告
本人博客文章,如果不加以说明则为
本人原创
!如果各位需要转载,请注明原作者及出处!谢谢!!
<
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
与我联系
发短消息
搜索
常用链接
我的随笔
我的空间
我的短信
我的评论
更多链接
我的参与
我的新闻
最新评论
我的标签
留言簿
给我留言
查看留言
我参加的小组
每日一句英语
蛋蛋日语学堂
每天一句日语
我的标签
模版引擎(4)
Linq(3)
验证码识别(2)
文件同步精灵(2)
Flex(1)
Socket5(1)
Template(1)
C#(1)
图片(1)
HTML图片(1)
随笔分类
C#(29)
(rss)
Sql(1)
(rss)
Web(3)
(rss)
其它(6)
(rss)
随笔档案
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月 (5)
2008年1月 (1)
2007年12月 (2)
2007年11月 (1)
2007年10月 (1)
2007年9月 (4)
最新评论
1. re: [原创]C#调用WMI更改本地网络IP设置
@Kingthy
谢谢 (wesleysun)
2. re: [原创]C#调用WMI更改本地网络IP设置
@wesleysun
上传了源码
(Kingthy)
3. re: [原创]C#调用WMI更改本地网络IP设置
错误 1 “SetIPAddress”方法没有采用“4”个参数的重载 C:\Documents and Settings\Administrator\My Documents\Visual Studi... (wesleysun)
4. re: [原创]C#调用WMI更改本地网络IP设置
怎么解决这个问题呢?
(wesleysun)
5. re: [原创]C#调用WMI更改本地网络IP设置
System.Management.ManagementBaseObject并不包含GetMethodParameters的定义
请问怎么会出现这种情况呢? (wesleysun)
阅读排行榜
1. 使用HTTP_X_FORWARDED_FOR获取客户端IP的严重后果(6142)
2. 163相册验证码图片的识别手记之一 --- 去除干扰(3236)
3. 使用Flash打造可定义界面风格的文件上传控件(3158)
4. 文件同步精灵(初版)-- 协议介绍(源码公开)(3095)
5. 开发基于UDP广播的小型局域网聊天室(2969)
评论排行榜
1. 163相册验证码图片的识别手记之一 --- 去除干扰(32)
2. 使用HTTP_X_FORWARDED_FOR获取客户端IP的严重后果(26)
3. 163相册验证码图片的识别手记之二 --- 识别 (19)
4. 使用Flash打造可定义界面风格的文件上传控件(17)
5. Visual Studio里的BUG??(17)