[点晴永久免费OA]客户端来源IP伪造攻击与防护指南
|
admin
2025年6月5日 17:45
本文热度 96
|
在现代Web架构中,反向代理、负载均衡器和CDN的广泛使用,使得服务器无法直接获取客户端的真实IP地址,为了实现用户身份识别、日志记录、地理定位和访问控制等功能,开发者通常使用某些HTTP请求头获取客户端来源IP,其中最常用的就是X-Forwarded-For(XFF)。本文将以XFF请求伪造为例,从漏洞介绍、实际案例、修复方式出发,详细了解客户端来源IP伪造攻击与防护。
X-Forwarded-For(XFF)是一个HTTP头字段,主要用于识别原始客户端的IP地址,通常由反向代理或负载均衡服务器添加。当应用程序依赖X-Forwarded-For 获取客户端IP进行安全控制时,攻击者可以伪造该头,绕过安全限制,例如:
·绕过IP访问控制:攻击者伪造XFF头绕过基于IP的白名单机制。
·日志污染与溯源欺骗:攻击者伪造XFF头,干扰日志记录,影响取证调查。
·Web应用防火墙 (WAF) 绕过:某些WAF依赖XFF进行访问控制,可能被绕过。
该漏洞的根本原因在于,服务端代码没有对X-Forwarded-For进行有效校验:
1. 直接信任XFF作为客户端IP:许多应用程序直接从HTTP头中读取X-Forwarded-For,并将其用于访问控制或日志记录。
2. 多层代理下错误解析:
·XFF头可能包含多个IP(如 X-Forwarded-For: 192.168.1.1, 10.0.0.1, 8.8.8.8)。
·如果服务器未正确解析,可能错误地使用攻击者提供的IP。
1. 拦截请求,添加X-Forwarded-For伪造 IP:
GET /admin HTTP/1.1
Host: target.com
X-Forwarded-For: 192.168.1.100
2. 发送请求,观察是否成功绕过访问限制或造成日志记录了伪造的IP。
burpFakeIP(https://github.com/TheKingOfDuck/burpFakeIP) 插件可自动插入X-Forwarded-For以及其他获取客户端IP的HTTP头,如X-Forwarded、X-Real-IP等。
插件中除X-Forwarded-For外,还包含 X-Real-IP等头,也是常见用于传递客户端 IP 的 HTTP 请求头:
·X-Forwarded-For:最常用的头,格式为 客户端IP, 代理1IP, 代理2IP。
·X-Forwarded:与X-Forwarded-For类似,但较少使用。
·X-Real-IP:通常由反向代理(如Nginx)设置,直接传递客户端IP。
·Ali-Cdn-Real-Ip:阿里云CDN专用的头,用于传递客户端真实IP。
·WL-Proxy-Client-IP:WebLogic服务器使用的头。
附录中列举了更详细的说明。
这些HTTP请求头在配置不正确的情况下,也会被伪造。下一节中将介绍相关案例。
某系统记录用户操作,例如登录、删除、修改系统配置等,可在系统日志功能中可查看。
经验证使用Proxy-Client-Ip可伪造客户端IP。
从代码段可以看出,服务端直接信任客户端传来的HTTP请求头作为客户端IP,导致伪造。
在搜索引擎搜索获取客户端IP的方式,大概率会得到类似代码,如果开发不理解代码原理,直接应用到业务中来,则会面临客户端请求头伪造的风险。
比如这段代码中,后端获取Proxy-Client-Ip和WL-Proxy-Client-IP,Proxy-Client-IP字段和WL-Proxy-Client-IP字段只在Apache(Weblogic Plug-In Enable)+ WebLogic搭配下出现,而实际业务中并未使用到Apache和Weblogic,因此这段代码并无实际作用,反而引入了漏洞。
如何防止XFF伪造,获取用户真实IP呢?
现在Web应用部署,一般会经过多重代理,如CDN、负载均衡、Nginx反向代理,以Nginx代理为例来看多重代理环境下如何获取真实客户端IP。
防御原理很简单,nginx不使用客户端传来的X-Forwarded-For,在直接对外的Nginx(即直接对外提供服务的Nginx)配置,修改nginx.conf。
1. 反向代理Nginx配置X-Forwarded-For
在nginx.conf中通过proxy_set_header传递X-Forwarded-For:
server {
listen 80;
location / {
proxy_pass <http://backend>;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
}
}
·$remote_addr:Nginx直接接收到的IP(通常是上游代理的 IP)。$remote_addr是获取的是直接TCP连接的客户端IP(类似于Java中的request.getRemoteAddr())这个是无法被伪造的。该设置可直接覆盖掉客户端传来的X-Forwarded-For头。
2. 应用服务器,以java应用为例
public String getClientIp(HttpServletRequest request) {
String xff = request.getHeader("X-Forwarded-For");
if (xff != null && !xff.isEmpty()) {
String[] ipList = xff.split(",");
return ipList[0].trim();
}
return request.getRemoteAddr();
}
这段代码的作用是获取并解析请求头X-Forwarded-For,经过代理,X-Forwarded-For形式可能为X-Forwarded-For:clientIP, proxy1, proxy2, proxy3
需提取第一个非代理IP。
如果中间经过多层代理,比如双重Nginx如何配置?
1. 第一层Nginx配置X-Forwarded-For
与5.1配置相同.
server {
listen 80;
location / {
proxy_pass <http://backend>;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
}
}
2. 第二层Nginx配置X-Forwarded-For
server {
listen 80;
location / {
proxy_pass <http://backend>;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
·这里需注意$proxy_add_x_forwarded_for:自动追加原始X-Forwarded-For头,以保留完整的IP链。
·也可以不做配置,直接透传Nginx1发送过来的请求。
3. 后端获取真实IP
与5.1相同
阅读原文:原文链接
该文章在 2025/6/6 12:12:16 编辑过