0X01 路由守卫机制分析
一、路由守卫是什么?
所谓鉴权重定向,可以理解为前端路由的“安保检查”:先核验身份(鉴权),没有权限就直接打发去登录页(重定向)。
通用重定向好比快递站通知:地址已变更,请到新地址取件。
鉴权重定向则像小区保安盘问:非业主禁止入内,先去门卫登记。
核心作用在于:进入页面前先执行校验,权限不足就进行拦截。
// 全局路由守卫 - 权限校验
router.beforeEach((to, from, next) => {
const isLogin = localStorage.getItem('token') // 获取登录token
const requiresAuth = to.matched.some(record => record.meta.requiresAuth) // 路由是否需要登录
// 需要登录但未登录,重定向到登录页
if (requiresAuth && !isLogin) {
next({
path: '/login',
query: { redirect: to.fullPath } // 记录原目标地址,登录后跳转回来
})
} else {
next() // 放行
}
})
二、现象描述
从 JS 文件中提取出 API 接口端点后,尝试未授权访问测试。无论是采用 GET/POST/PUT/DELETE 全方法 HTTP 探测,还是利用 Bulk URL Opener 一键打开所有 URL,均未发现有效入口(参数寻找也极为头疼)。扫了半天全是登录页或者 404,这活儿实在没法干。所有请求均被重定向至登录页面或其他无关地址,无法触达后端业务逻辑。
三、根因分析
这种现象通常源于 Vue 前端路由守卫机制,或是前端与后端多重因素的叠加:
- 前端路由拦截:Vue Router的beforeEach钩子实施全局鉴权校验
- 请求预处理:未携带有效 Token 的请求在客户端层面即被阻断,根本不会真正发送至服务端。
- 后端防护:服务端 API 可能同步启用了 JWT/OAuth2 校验,形成了前后端的双重验证闭环。
// 你的 Bulk URL Opener 一键打开所有 URL,就是因为这个:
router.beforeEach((to, from, next) => {
if (!token) {
next('/login') // ← 前端直接拦住,请求根本没发到后端!
}
})
四、突破方案
面对这种情况,常规思路无非是源码考古、地图寻宝、时空穿越、社会工程……手动审计 JS 找绕过点 hook,参数 fuzz 更是找到瞎眼。
1. 扒app.[hash].js路由表,定位meta: { auth: false }的疏漏
2. 解析*.js.map源映射,检索被注释的debug路由
3. Burp抓包改Host头,绕过前端直捅后端API
4. 对比历史版本路由守卫迭代,定位防护降级节点
5. 分析JS报错与console输出,提取硬编码线索
其实完全不用这么费劲。Vue 路由守卫的绕过可以不依赖技巧,直接上工具即可。关键在于跳过前端这出戏台,让浏览器自己拼接参数。
0X02 靶场演示
方式一、直接使用插件绕过
直接使用插件提取路径虽然未必齐全,还需要配合调试(不过确实减轻了不少测试压力)。
工具一号地址:https://github.com/flagqaz/AegisScope
正常情况下用该工具就能满足大多数需求,不仅能识别 Vue 框架、绕过 Vue 路由,还具备许多其他辅助功能。



需要留意的是,插件只能提取源码中标准写法的 URL,对于 Vue 路由对象、动态参数、条件拼接的路径往往容易遗漏。
方式二、抓包修改返回包的值
通过 Burp / Yakit 工具拦截后端响应,修改数据内容(例如将 role: "user" 改为 role: "admin"),观察前端是否会仅凭返回数据渲染敏感界面(跳转并访问对应 API 接口携带敏感数据)。



测试的本质是验证前端是否过度信任后端数据,而非验证后端权限校验是否完善。后端接口本身仍需单独进行测试。
方式三、通过修改浏览器本地存储
在控制台或 Application 面板直接篡改 localStorage / sessionStorage 中的 token、用户信息等字段。
如果前端仅依赖本地存储做权限判断,修改后即可直接绕过。但要注意,刷新页面后若后端验证 token 失效,页面功能可能仍会报错。

方式四、通过分析JS直接控制台修改
在 Sources 面板找到路由守卫或权限判断逻辑,下断点或直接在控制台覆盖变量、函数。
这需要 Vue 实例或 router 对象暴露在全局(如 window.app、window.router),否则需借助 Vue DevTools 或通过断点注入获取。目的是直接访问类似 /dashboard 的受限页面。

history.pushState(null, null, '/dashboard') // ① 修改浏览器地址栏 URL
window.dispatchEvent(new PopStateEvent('popstate')) // ② 触发 popstate 事件

0X03 实战演示
当然还有一种情况:路由守卫虽然显示已清除,但工具一号无法清理干净,这时该如何解决?
工具二号地址:https://github.com/0xsdeo/AntiDebug_Breaker
工具二号脚本会清除 Vue Router 的跳转方法,但如果清除之后依然发生跳转,通常有两方面原因:
一方面:注入的脚本还没来得及清除跳转方法,网站就已经调用了方法进行跳转。此时可以考虑手动替换 JS 来清除跳转方法。
另一方面:代码中调用的可能并非 Vue Router 的跳转方法。这时可以开启反调试板块中的 hook close 或 hook history 脚本,或者打开页面跳转 JS 代码定位通杀方案脚本,定位到跳转的函数并替换清除。
有个值得思考的问题:为什么 FindSomething 找不到路径?
原理在于其正规则匹配 URL 模式:
// FindSomething 举例内部结构
const patterns = [
/['"](\/[^'"]+)['"]/g, // 匹配 "/xxx"
/https?:\/\/[^'"\s]+/g, // 匹配 http://xxx
/fetch\(['"]([^'"]+)['"]\)/g, // 匹配 fetch("xxx")
/axios\.[a-z]+\(['"]([^'"]+)['"]\)/g // 匹配 axios.get("xxx")
]
而我们需要扫描的内容往往是打包后的代码:

针对上面的打包代码,扫描结果可能如下:
// 能匹配到的
axios.get("/api/users") // 标准的 HTTP 请求
// 匹配不到的
{ p: "/admin", c: ... } // 不是标准 URL 格式
{ p: "/user/:id", c: ... } // 带参数,不是真实字符串
{ p: "/api-test", c: ... } // 在 Vue 路由对象里
未登入状态下,利用 VueCrack 等工具可以直接提取并跳转 URL:

但存在“二次跳转”现象:先渲染目标页面,随即被路由守卫拦截并重定向至登录页。视觉上呈现为“闪屏”效果。
遇到“闪屏”情况,有个小技巧:Burp 卡包。通过卡住数据包来终止前端后续的跳转逻辑。

此外还可以尝试断点调试法、网速节流法、路由钩子覆盖、本地存储伪造等。其实也不用这么复杂,直接用 AntiDebug Breaker 工具处理即可:


目前最好用的 Vue 跳转处理工具当属 AntiDebug Breaker。针对“二次跳转”现象(即视觉上的“闪屏”效果),它的处理效果相对较好。如果仍然出现“闪屏”,那就只能考虑手动处理了。类似的 Vue 未授权绕过技巧与实战经验,在云栈社区中也有不少深入的讨论与案例沉淀。