客户端来源IP伪造攻击与防护指南 2025-06-17 网络安全 暂无评论 22 次阅读 在现代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。 #漏洞测试方式 以Burp Suite为例。 ##Burp Suite手工测试 1.拦截请求,添加X-Forwarded-For伪造 IP: ``` GET /admin HTTP/1.1 Host: target.com X-Forwarded-For: 192.168.1.100 ``` 2.发送请求,观察是否成功绕过访问限制或造成日志记录了伪造的IP。 ##Burp插件 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。  污染日志记录伪造IP地址。  经沟通得知获取Client 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作为反向代理  防御原理很简单,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 ; 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(); // 仅提取第一个非代理 IP } return request.getRemoteAddr(); } ``` 这段代码的作用是获取并解析请求头X-Forwarded-For,经过代理,X-Forwarded-For形式可能为`X-Forwarded-For:clientIP, proxy1, proxy2, proxy3` 需提取第一个非代理IP。 ##两层Nginx代理  如果中间经过多层代理,比如双重Nginx如何配置? 1.第一层Nginx配置X-Forwarded-For 与5.1配置相同. ``` server { listen 80; location / { proxy_pass ; 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 ; 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相同 附录 常见用户传递客户端IP的HTTP请求头:  转自https://mp.weixin.qq.com/s/DhEm8h_m4aSf8TZNduJ8KQ 标签: header 本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。