在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地址 !!
下面是测试代码:
复制 保存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 " 文件代码:
复制 保存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.即是不要再理会代理情况.你的建议又是怎样呢 ???
试试
复制 保存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;
}
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地址 !!
下面是测试代码:
复制 保存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 " 文件代码:
复制 保存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.即是不要再理会代理情况.你的建议又是怎样呢 ???
试试
复制 保存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;
}