前端路由跳转被用户输入污染的核心在于location.href、replace()或history.pushState()的目标URL是否直接拼接未校验的用户输入,常见污染源包括location.search、hash、路径片段及localStorage读取值,需通过开发者工具检查参数、代码审计和载荷测试验证校验逻辑有效性。

如何识别前端路由跳转是否被用户输入污染
前端路由跳转出问题,核心在于 window.location.href、location.replace() 或 history.pushState() 的目标 URL 是否直接拼接了未校验的用户输入。常见污染源包括 location.search(如 ?redirect=/admin)、location.hash、URL 路径片段(如 /login?from=javascript:alert(1))或 localStorage 读取值。
检测时先打开开发者工具,在 Console 中手动执行:
new URLSearchParams(location.search).get('redirect')
再观察返回值是否可被外部控制;接着搜索代码中所有对 location 对象的赋值操作,重点关注是否出现类似这样的写法:
-
location.href = url(其中url来自getURLParam('next')或decodeURIComponent(hash)) -
router.push(untrustedInput)(Vue Router / React Router v5 等未做校验的调用) history.pushState(null, '', userInput)
白名单校验是否真正生效
很多项目写了“校验逻辑”,但实际形同虚设。典型失效场景包括:
立即学习“前端免费学习笔记(深入)”;
- 只检查
url.startsWith('/'),却忽略//evil.com(双斜杠开头是合法协议相对 URL,会跳转到外部) - 用
includes('example.com')判断域名,但攻击者构造https://evil.com.example.com绕过 - 校验发生在跳转之后,比如先赋值
location.href = input,再调用checkUrl()—— 此时页面已跳走 - 正则校验过于宽松,例如
/^\/[a-z0-9/]+$/i允许/../external?url=javascript:alert(1)
验证方法:在跳转前断点,把可疑 url 变量拖进 Console,手动运行校验函数,传入 '//malicious.site'、'javascript:alert(1)'、'data:text/html,<script>alert(1)</script>' 等测试载荷,看是否被拦截。
React/Vue 路由器的 to 参数是否被滥用
现代框架的路由 API 表面安全,实则容易误用。比如:
- React Router v6 的
useNavigate()接收字符串时,若传入searchParams.get('redirect')且未清洗,就会触发跳转 - Vue Router 的
router.push({ path: userInput }),如果userInput是'/login?next=https://attacker.com',后续组件可能再次解析并跳转 - Nuxt 的
onBeforeRouteUpdate钩子里直接router.push(to.query.redirect)
关键判断点:所有动态生成的 to 值,是否经过 isInternalPath() 类函数校验?是否只允许绝对路径(/xxx)或预定义命名路由({ name: 'Dashboard' })?避免接受任意字符串或对象形式的 path。
服务端 fallback 配置是否掩盖了前端路由问题
单页应用(SPA)常配置 Nginx/Apache 将 404 请求 fallback 到 index.html。这个配置本身合理,但会掩盖一个严重问题:当用户访问 /static/js/app.123.js 却因路径错误返回了 index.html 内容时,浏览器会尝试把 HTML 当 JS 执行,报错 Unexpected token ' —— 这说明前端路由规则和静态资源路径不一致,也可能意味着 <code>redirect 参数被用于构造非法资源路径。
排查方式:
- 在 Network 面板筛选 JS/CSS 请求,查看响应内容是否为 HTML(尤其注意 Size 异常小或大)
- 检查构建输出目录结构,确认
public/下的资源路径与router.base或 WebpackpublicPath配置是否匹配 - 若发现
/login?redirect=/static/js/app.js导致加载失败,说明该 redirect 参数未做路径合法性过滤,可能被用于路径遍历或资源探测
真正危险的不是跳转本身,而是前端路由逻辑把用户输入当作可信路径来解析、拼接、甚至透传给服务端——这种信任一旦建立,就很难靠单点校验堵住所有出口。



















