一句话定义:开放重定向(Open Redirect)指网站把一个由用户可控的参数当成跳转目标,却不做校验,导致攻击者能借“可信域名”把用户送到任意站点。
next 参数怎么变成钓鱼入口
几乎所有网站都有登录页,也都希望用户登录后回到原来的位置。常见做法是给登录链接加个参数,例如 /login?next=/orders/2024,用户通过验证后,服务端读 next 的值,返回一个 302 跳转。问题出在这个值没有经过校验,就交给浏览器去跳。
攻击者只需构造 https://bank-you-trust.com/login?next=https://bank-youtrust.com。受害者看到的链接,域名确实是官方域名,因此会放心输入账号密码;认证在真实站点完成,全是真流程。登录成功后页面一跳,落到攻击者准备好的仿冒页,上面写着“会话已过期,请重新登录”。这一次,账号密码就交给了第三方。整个过程里,官方站点的域名恰好起了“信任担保”的作用,这是它比普通钓鱼链接更危险的原因。
打个比方:前台保安认真核对了访客有没有门禁卡,却不管访客出门后上了谁的车。卡是真的,车是假的。
和相邻概念的区别
| 概念 | 谁被利用 | 结果 |
|---|---|---|
| 开放重定向 | 站点的可信域名 | 用户被送去外部钓鱼页 |
| 反射型 XSS | 站点的页面渲染 | 攻击者脚本在站内执行 |
| SSRF | 服务器发出请求的能力 | 内网被探测 |
| 普通钓鱼站 | 相似域名 | 用户自己点错 |
四者的共同点是“借信任”,但开放重定向借的是域名本身;它不执行代码、不碰服务器,所以常被扫描器标为低危。可一旦出现在登录、支付、OAuth(Open Authorization)回调链路上,危害会明显放大,因为 OAuth 的 redirect_uri 一旦被放宽匹配,授权码就可能被送到别处。
白名单该怎么写
第一选择是不传完整 URL,只传站内路径。服务端校验时注意几点:解码后再判断,且只解码一次,防止双重编码绕过;必须以单个 / 开头,第二个字符不能是 / 或 \,因为 //evil.com 是协议相对地址,而部分浏览器会把 \ 当作 /;拒绝含 :、@、\ 和控制字符的值。更稳的写法是用标准 URL 解析器把它和本站基准地址解析一次,再比较解析结果的 origin 是否等于本站。
如果业务确实需要跳外站,就维护静态白名单:一条条列出精确域名,不做后缀匹配,否则 good.com.evil.com 和 evil.com/good.com 都能钻过去;还要当心 https://good.com@evil.com 这种 userinfo 欺骗,以及外观相似的国际域名。原则是用白名单,不用黑名单正则,并且默认值设为首页。跳转前加一个“即将离开本站”的中间页,成本很低。主流框架和网关多数已有现成配置项,具体支持范围以官方页面为准。
对普通职场人:看到“登录后自动跳转”的链接,留意 next=、redirect=、return= 后面的内容。对从业者:这类漏洞用代码扫描很容易漏,评审时把“所有跳转入口”列成清单逐个过一遍,比逐行审查更可靠。
