:安全软件给出提示中的 XFF绕过 是怎么回事?原理是什么?如何防范?
<script Language="javascript">
alert("当前IP(47.111.14.70)不在WebVPN白名单中,请重新登录验证。");
window.top.document.location.href="/webvpn.html";
</script>
漏洞概况:xff绕过
漏洞简介:xff可以绕过,暂未成功获取白名单ip
漏洞危害:通过XFF漏洞可进一步爆破系统白名单IP,并可以此进一步攻击系统。
漏洞链接:test.cn
漏洞详细利用过程:直接修改x-forward-for,响应包可查。
工作建议:关闭XFF返回提示,并限制内网IP访问。

XFF(X-Forwarded-For)绕过原理、你这个案例解读、防范方案
一、XFF 是什么
X-Forwarded-For(简称 XFF)是一个HTTP 请求头,标准用途:
当请求经过代理、负载均衡、WebVPN、CDN 转发时,代理把原始客户端真实 IP写到这个头里面,传给后端业务服务器。
格式示例:
X-Forwarded-For: 47.111.185.70, 10.0.0.1
第一个 IP:原始客户端 IP;后面是一路经过的代理 IP。
⚠️ 重点:XFF 请求头是客户端可以随便伪造的!
浏览器 / 发包工具可以任意自定义 XFF 头,填任何 IP 字符串,服务器默认不会自动校验真假。
二、这个「XFF 绕过白名单」漏洞原理(对应你截图场景)
你的 OA 系统做了IP 白名单校验,逻辑是:
读取请求头 X-Forwarded-For 里的 IP,判断这个 IP 是否在白名单;
如果不在,弹出 JS 弹窗,跳转 webvpn 登录页(就是你看到那段 alert 脚本)。
漏洞根源
开发错误地直接信任 XFF 头部的 IP 作为访问者真实 IP。
攻击者不需要真的从白名单 IP 发起访问,只需要在 HTTP 请求里手动添加请求头:
X-Forwarded-For: 【白名单内的IP地址】
后端读到 XFF 头里这个伪造 IP,判定为白名单 IP,放行访问 → 也就是 XFF 绕过。
漏洞描述写的:直接修改x-forward-for,响应包可查
含义:修改请求里 XFF 头的值,服务器会读取并使用这个 IP 做判断;从返回的响应内容(返回的页面 / JS)能看到服务器识别到了这个 XFF 里的 IP。
你看到的弹窗 JS:
alert("当前IP(47.111.14.70)不在WebVPN白名单中,请重新登录验证。");
window.top.document.location.href="/webvpn.html";
这个 IP 47.111.14.70 就是后端从 XFF 头里面读出来展示的 IP。
证明:后端确实把 XFF 头当成可信 IP 来源。攻击者只要把 XFF 改成白名单 IP,后端就不再弹出这个拦截提示,直接放行。
漏洞简介写「暂未成功获取白名单 ip」:是扫描器只验证了【XFF 可被后端读取】这个漏洞存在,但扫描器还不知道白名单里面具体有哪些 IP,所以还没完成完整绕过。一旦拿到白名单 IP 列表,就能直接绕过 IP 限制。
漏洞危害
- 绕过 IP 白名单访问 OA 后台、内网系统;
- 结合账号爆破:在外网直接暴力破解 OA 账号,原本只允许内网 IP 登录,现在 XFF 伪造 IP 突破地域限制;
- 日志失真:所有访问日志里记录的 IP 都是伪造的,出事之后溯源困难。
三、为什么会出现这个漏洞?(典型开发误区)
系统部署在 WebVPN / 反向代理后面,开发为了拿到真实用户 IP,直接写代码:
优先读取 X-Forwarded-For 头,拿里面 IP 做白名单校验。
✅ 正确做法:XFF 只能由前端可信代理写入,业务代码不能直接信任 XFF 头
❌ 错误做法:业务代码直接解析 XFF,拿它做鉴权 / 白名单判断(你 OA 现在就是这个情况)
四、工作建议落地(对应报告建议:关闭 XFF 返回提示 + 限制内网 IP 访问)
1. 核心修复方案(最重要)
IP 白名单校验,绝对不要使用 X-Forwarded-For 头部做判断
- 如果前端有可信反向代理 / 负载均衡 / WebVPN:
在代理层把真实 IP 传递给后端,后端只信任代理层传递过来的特殊变量(不是原生 XFF 头)。
例如 Nginx 代理,代理上配置
real_ip模块,后端读取 Nginx 传递的真实 IP 变量;代理要丢弃客户端传入的原始 XFF,不能透传用户自定义 XFF。
也就是:用户提交的 XFF 头,在代理这一层直接删掉,不让传到后端 OA。只由代理自己填充可信 IP。
- 如果没有可信前置代理:直接用 TCP 连接源 IP(socket 来源 IP)做 IP 白名单,完全不读取 XFF。
一句话原则:所有用于鉴权、白名单、安全策略的 IP,必须是可信层给出的 IP;客户端可控的 HTTP 头一律不能用于安全判断。
2. 关闭 XFF 信息回显(报告第一条建议)
现在系统页面直接把从 XFF 读到的 IP 展示在 alert 弹窗里:
当前IP(47.111.14.70)不在WebVPN白名单中。
👉 这属于信息泄露。
攻击者可以通过不断修改 XFF,看页面返回内容,暴力探测白名单网段 / IP。
修复:弹窗不要回显识别到的 IP,只提示「IP 不在访问白名单,请通过 WebVPN 访问」,不要输出 IP 文本。
3. 限制内网 IP 访问(报告第二条建议)
- 外网入口层面(防火墙 / NGINX/WAF):禁止公网直接访问 OA,只允许 WebVPN 接入通道;
- OA 本身:即使 XFF 被篡改,在网络层面阻断公网直连,多层防护;
- WebVPN 本身做二次身份认证,不要只靠 IP 做唯一信任依据。
4. WAF 层面加固
WAF 增加规则:检测异常 XFF 头,直接拦截带有伪造 XFF 的请求;
记录真实 TCP 源 IP 用于审计日志,日志不要只记录 XFF 里的伪造 IP。
五、快速验证方法(确认漏洞是否修复)
用 Postman/Burp 发包,添加请求头:
X-Forwarded-For: 192.168.1.1
- 如果服务器读取了 192.168.1.1并用于判断,漏洞依然存在;
- 如果忽略这个 XFF 头,只认真实连接 IP,漏洞修复。
六、补充误区提醒
- XFF 本身不是漏洞,错误信任 XFF 用于安全校验才是漏洞;
- 不要简单 “删掉 XFF 头” 了事:如果你的 OA 前面确实有 WebVPN 代理,你需要由可信代理重写 XFF,清除客户端自定义 XFF,后端使用代理交付的真实 IP;
- IP 白名单只是辅助防护,不能作为唯一身份认证,就算 IP 合法,仍然要账号密码 / 双因素认证。
Nginx real_ip 模块配置(修复 XFF 信任漏洞)
前提:Nginx 需要编译带 ngx_http_realip_module,很多云服务商、yum/apt 安装的 nginx 自带;
作用:丢弃客户端传来的原始 X-Forwarded-For,由可信代理写入真实 IP,后端业务不再读取客户端可控的 XFF
场景:Nginx 作为前置反向代理 / WebVPN 前置,后端是你的 OA 系统(test.cn)
重要说明
set_real_ip_from 填写上游可信代理的 IP 段(也就是 WebVPN / 前端负载均衡服务器 IP,不是用户 IP),只有从这些可信 IP 过来的请求,Nginx 才接受它传递的 IP;外网用户直接访问的请求,Nginx 不会采信 XFF。
完整站点配置示例
server {
listen 80;
server_name test.cn;
# ========== real_ip 核心配置 ==========
# 填写可信代理(WebVPN/前置LB)的IP,可以写多个,支持CIDR网段
set_real_ip_from 10.0.0.0/24;
set_real_ip_from 192.168.1.0/24;
set_real_ip_from 172.16.0.0/12;
# 从代理传递的 X-Forwarded-For 获取真实客户端IP
real_ip_header X-Forwarded-For;
# 从XFF链里取第一个非内网代理IP作为真实IP
real_ip_recursive on;
# =====================================
# 关键:删除客户端自己带的XFF,防止伪造头透传到后端OA
proxy_set_header X-Forwarded-For $real_ip_from;
# 常规代理转发配置
location / {
proxy_pass http://你的OA后端内网地址:端口;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 这里 X-Real-IP 现在就是经过real_ip模块解析后的真实客户端IP
}
}
两种模式区分(重点,不要搞混)
模式 A:Nginx 直接对外(没有前置 WebVPN)
这种场景完全不能信任 XFF,直接删掉所有 XFF 头,后端业务读取$remote_addr(TCP 原生连接 IP)
server {
listen 80;
server_name test.cn;
location / {
proxy_pass http://OA后端;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 清除客户端传入的XFF,不向后端传递
proxy_set_header X-Forwarded-For "";
}
}
模式 B:WebVPN 在 Nginx 前面(WebVPN 是可信上游)
就用上面第一段 real_ip 完整配置,set_real_ip_from 只填 WebVPN 服务器 IP。
只有 WebVPN 服务器发来的请求,Nginx 才认可它的 XFF;公网用户直接带伪造 XFF 访问,Nginx 直接忽略。
验证是否生效(修复测试命令)
用 curl 模拟伪造 XFF 头访问 OA:
curl -H "X-Forwarded-For: 192.168.1.100" http://test.cn
修复成功标准:
- 后端 OA 读取 IP 不再是
192.168.1.100;
- 弹窗不再识别这个伪造 IP,IP 白名单校验使用 TCP 真实源 IP;
- 后端日志记录的 IP 是真实访问 IP,不是 curl 里伪造的 XFF。
配套安全建议(和漏洞报告对应)
- OA 后端代码:修改 IP 校验逻辑,不再读取原始
X-Forwarded-For,改为读取 Nginx 传过去的X-Real-IP;
- 页面弹窗:移除 IP 回显,不要输出识别到的 IP 地址(防止扫描器爆破白名单网段);
- 网络层面:尽量禁止公网直连 OA 端口,仅开放 WebVPN 接入;防火墙只放行 WebVPN 服务器 IP 访问 OA。
检查 nginx 是否支持 real_ip 模块
nginx -V | grep realip
输出含有 --with-http_realip_module 代表支持;没有的话需要重新编译 Nginx。
场景确认:Nginx 直接对外,Nginx 反向代理 OA(前面没有 WebVPN / 其他 LB)
核心原则:完全不信任客户端提交的 X-Forwarded-For,全部丢弃,IP 白名单用 TCP 原生连接 IP $remote_addr
此时不能开 real_ip,因为没有可信上游代理,客户端 XFF 可以随便伪造,一开就回到 XFF 绕过漏洞。
完整可用 nginx.conf server 块(直接复制使用)
server {
listen 80;
server_name test.cn;
# 可选:这里可以在Nginx层先做IP白名单(推荐,在进入OA应用前拦截)
# allow 192.168.1.0/24;
# deny all;
location / {
proxy_pass http://OA后端内网IP:端口;
proxy_set_header Host $host;
# 传递TCP原生真实连接IP,这个是不能被客户端伪造的
proxy_set_header X-Real-IP $remote_addr;
# 关键:清空客户端自带的X-Forwarded-For,禁止把用户伪造的XFF传给OA后端
proxy_set_header X-Forwarded-For "";
}
}
对应 OA 应用侧代码修改(必须做,只改 Nginx 不够!)
原来 OA 程序是读取 X-Forwarded-For 头拿来做 IP 白名单判断 → 这就是漏洞根源
改成:读取 X-Real-IP 请求头做 IP 校验,不要再读 X-Forwarded-For。
原理:X-Real-IP 由 Nginx 赋值为 $remote_addr(TCP 连接源 IP),客户端无法伪造。
客户端自己在请求里加 X-Real-IP 没用,Nginx 的proxy_set_header会覆盖掉它。
验证命令(测试漏洞是否修复)
curl -H "X-Forwarded-For: 192.168.1.1" -H "X-Real-IP: 10.0.0.1" http://test.cn
修复成功判断:
- OA 识别到的 IP 是你本机真实公网 IP,不是 192.168.1.1,也不是 10.0.0.1
- 页面弹窗不再读取伪造 XFF 里的 IP,不会被 XFF 篡改 IP 判定
- 日志记录 IP = 真实 TCP 源 IP
额外加固建议(匹配扫描报告)
- 关闭页面 IP 回显:alert 弹窗去掉展示 IP 的文本,不要输出识别出来的 IP,避免攻击者遍历探测白名单网段
原 js:
alert("当前IP(47.111.14.70)不在WebVPN白名单中,请重新登录验证。");
修改成:alert("访问IP不在白名单,请通过WebVPN重新登录验证。");
- 多层防护:Nginx 层面叠加 IP 白名单(推荐)
在 server 块里增加(放在 location 外面):
-
allow 你的OA允许访问的公网/内网IP;
deny all;
Nginx 直接在接入层拦截非法 IP,请求根本进不到 OA 应用。
- 日志规范:业务日志记录
X-Real-IP,审计溯源使用 TCP 源 IP,不要记录 XFF。
注意坑点
- ❌ 不要启用
real_ip 模块!你现在架构 Nginx 直接对外,没有可信前置代理,开启 real_ip 会引入 XFF 伪造风险。
- ❌ 不要写
proxy_set_header X-Forwarded-For $remote_addr; 这种写法,后端代码万一还是读 XFF,风险依旧存在,直接置空最稳妥。
- ✅ IP 白名单只做辅助安全手段,账号登录仍然保留密码、验证码、二次验证,不能只靠 IP 鉴权。
阅读原文:点击这里
该文章在 2026/10/12 10:31:13 编辑过