从源码解析Vue路由守卫绕过原理

admin 2026-01-17 01:55:39 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细解析了Vue路由守卫的绕过原理,指出客户端守卫仅用于UI控制而非安全防御。文章通过代码审计演示了两种绕过方式:一是直接篡改Pinia/Vuex内存中的认证状态;二是在本地存储中伪造Token。核心结论是前端防护不可靠,必须在服务端进行严格的权限验证。 综合评分: 88 文章分类: WEB安全,代码审计,安全开发,漏洞分析


cover_image

从源码解析 Vue 路由守卫绕过原理

船山信安

2026年1月15日 17:00 湖南

基础知识:什么是 Vue 路由守卫?

在 Vue.js 单页应用(SPA)中,页面跳转并不会刷新浏览器,而是由 vue-router 动态替换组件。为了控制用户访问权限(例如:未登录用户不能访问后台),开发者通常会使用 全局前置守卫

简单来说,路由守卫就像是小区门口的保安:

  • to: 你要去哪里?(目标路由)

  • from: 你从哪里来?(来源路由)

  • next: 是否放行?(控制跳转)

一个典型的守卫代码如下:

router.beforeEach((to, from, next) => {
  // 如果目标路由需要权限,且用户未认证
  if (to.meta.requiresAuth && !isAuthenticated) {
    next('/login'); // 拦截,踢回登录页
  } else {
    next(); // 放行
  }
});

绕过方式一:客户端状态直接篡改

  • 场景: 应用依赖前端内存中的状态(如 Pinia/Vuex)来判断用户是否登录

  • 目标: 不登录直接访问 Admin 页面

代码审计

我们拿到了靶场的源码,重点关注两个文件:src/router.js(路由配置)和 src/stores/auth.js(状态管理)

审计 src/router.js

// 创建 Vue Router 实例
const router = createRouter({
  // 使用 HTML5 History 模式(需要服务器配置支持)
  history: createWebHistory(),
  // 定义路由表
  routes: [
    // 首页路由,路径 '/' 对应 Home 组件
    { path: '/', component: Home },
    // 登录页路由,路径 '/login' 对应 Login 组件
    { path: '/login', component: Login },
    // 管理员页面路由
    {
      path: '/admin',
      component: Admin,
      // [1] meta 字段用于存储路由元信息
      // requiresAuth: true 标记此路由需要用户认证才能访问
      meta: { requiresAuth: true }
    }
  ]
})

// 注册全局前置守卫,在每次路由跳转前执行
router.beforeEach((to, from, next) => {
  // [2] 获取认证状态存储(假设使用 Pinia)
  // 注意:在 Vue 3 中,需确保在 setup 上下文中调用 useAuthStore()
  const authStore = useAuthStore()

  // [3] 核心判断逻辑:检查目标路由是否需要认证且用户未登录
  if (to.meta.requiresAuth && !authStore.isAuthenticated) {
    // 输出警告信息到控制台
    console.warn('⛔ Access Denied: User not authenticated.')
    // 跳转到登录页面,中断当前导航
    next('/login')
  } else {
    // 放行路由跳转(包括不需要认证的路由和已认证用户)
    next()
  }
})

审计 src/stores/auth.js

export const useAuthStore = defineStore('auth', () => {
  // 【漏洞警示:纯客户端状态】
  // 此 isAuthenticated 状态仅在客户端内存中维护,
  // 攻击者可通过浏览器开发者工具轻松修改其值为 true,
  // 从而绕过前端路由守卫的认证检查
  const isAuthenticated = ref(false) // [4] 默认未认证状态
  // ...

  // 暴露状态和方法供组件使用
  return { isAuthenticated, login, logout }
})

审计分析

isAuthenticated 只是一个普通的 Vue ref,存储在浏览器的内存中。整个认证逻辑完全运行在客户端

既然判断依据只是浏览器内存中的一个变量,作为客户端的控制者,我们可以随意修改这个变量的值

绕过方式二:本地存储伪造

为了实现“保持登录状态”,开发者通常会将 Token 存储在 localStoragesessionStorage

很多开发者写出了类似这样的路由守卫代码:

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth) {
    const token = localStorage.getItem('token');
    // 仅仅检查 Token 是否存在 (Existence Check)
    if (token) {
      next(); // 放行
    } else {
      next('/login'); // 拦截
    }
  } else {
    next();
  }
});

打开浏览器控制台输入

localStorage.setItem('token', 'i_am_a_hacker_token');

来源:https://xz.aliyun.com/  感谢【用户wEXYxrAEhI】


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:船山信安 《从源码解析 Vue 路由守卫绕过原理》

评论:0   参与:  0