某天深夜,跳转你的漏洞用户收到一条私信:“点击链接领取红包”。链接前缀是解决你的域名,结尾却跟着一串诡异的跳转字符。他点下去,漏洞浏览器跳到了一个仿冒的解决登录页面——密码就这么没了。整个过程不超过三秒,跳转你甚至不知道漏洞出在哪。漏洞
url重定向漏洞的解决本质,是跳转服务器信任了用户提供的“跳转地址”参数。很多开发者图省事,漏洞直接拼接参数就返回302响应。解决攻击者把参数改成钓鱼网站,跳转你的漏洞服务器就成了帮凶。这玩意儿比想象中的解决普遍——登录跳转、支付回调、分享链接,几乎每个带redirect参数的地方都可能中招。
最傻的修复方式是黑名单过滤。你封掉evil.com,人家换evil.org;你封掉http,人家用https加@符号绕过。见过最离谱的案例,是某大厂只检查参数开头是否包含自己的域名,结果攻击者构造“https://yourdomain.com.attacker.com”直接秒破。正则表达式在这事上就是个无底洞,你永远猜不到攻击者的编码技巧。
根治的办法只有一个:服务端维护一份白名单域名列表。用户传过来的参数不是域名,而是一个索引值——比如“next=profile”对应“/user/profile”,“next=logout”对应“/logout”。服务器拿到索引查表,查不到就默认跳首页。这招简单粗暴,但彻底斩断了用户输入对跳转地址的控制权。
要是业务场景复杂,必须支持动态URL怎么办?那就校验解析后的host,而不是字符串前缀。用标准库的URL解析函数,取出host字段,再跟白名单里的域名做精确比对。别手写字符串判断,别用contains方法——PHP的parse_url、Java的URI类、Python的urlparse,都是现成的工具。注意协议是http还是https无所谓,关键是host必须完全匹配。
还有个容易忽略的坑:跳转参数被二次编码。攻击者把“%2F%2Fevil.com”编码成“%252F%252Fevil.com”,有些框架会自动解码一次,你的校验逻辑要是放在解码之前,就白干了。正确姿势是先拿到框架处理完的最终URL,再做host校验。拿不准就自己手动解码三层,再跑校验。
更隐蔽的是间接跳转。攻击者不直接传你的域名,而是传一个你自己网站上的开放重定向地址——比如“/link?target=evil.com”。你要是只校验参数开头是“/”就放行,攻击者绕一圈还是能跳到钓鱼站。所以白名单校验必须递归执行,把最终跳转的URL也拉进来查一遍。
我见过最惨的案例是某电商平台,跳转参数交给前端JS处理。后端返回一个带redirect字段的JSON,前端拿到就location.href赋值。攻击者直接改请求包里的JSON,后端压根没校验。这种前后端分离的架构,最容易把安全校验漏在中间。记住:所有跳转逻辑必须在后端完成,前端只负责接收最终的、校验过的URL。
最后补一刀:日志审计不能省。每次跳转都记录原始参数、解析后的host、校验结果。出了事能追溯,没出事也能定期检查有没有人尝试绕过。安全不是一锤子买卖,是持续对抗的过程。你封住一个洞,攻击者就会找下一个。把校验逻辑做成公共函数,所有项目统一调用,别让每个开发自己写一套——那才是漏洞的温床。
顶: 323踩: 5






评论专区