越权漏洞(Privilege Escalation)是Web与APP安全中最常见、危害最直接的漏洞类型之一,分为水平越权(同权限用户间非法访问资源,如普通用户查看他人订单)和垂直越权(低权限用户访问高权限功能,如普通用户修改管理员密码)。这类漏洞的核心成因是“权限校验逻辑缺失或不严谨”,挖掘门槛低但实战价值高——攻击者常通过越权直接获取核心数据(如用户隐私、财务信息)或接管系统。

本文通过10个覆盖Web后台、API、移动端、云服务的实战案例,拆解越权漏洞的挖掘思路、利用步骤与防御方案,帮你从“识别漏洞”进阶为“系统化挖掘越权”的高手。

一、基础认知:越权漏洞的核心分类与成因

在进入案例前,先明确越权的核心逻辑,避免混淆:

类型 定义 典型场景 危害
水平越权(Horizontal) 同权限角色间,A用户访问/修改B用户的专属资源 普通用户查看他人订单、私信、个人信息 数据泄露(隐私、财务)
垂直越权(Vertical) 低权限角色访问/操作高权限角色的功能 普通用户访问管理员后台、修改管理员密码、调用商户级API 系统接管、业务逻辑篡改

核心成因:后端未对“资源归属”或“用户权限等级”做强制校验,依赖前端隐藏(如按钮、URL)或简单参数判断,具体包括:

  1. 仅校验“登录状态”,未校验“资源是否属于当前用户”;
  2. 权限判断在前端(如隐藏高权限URL),后端无二次校验;
  3. 用户标识参数(如user_idorder_id)可控,且未关联当前登录用户;
  4. 会话凭证(JWT、Cookie)未绑定权限信息,仅验证有效性;
  5. 第三方接口集成时,未传递或校验用户权限。

二、10个实战案例:覆盖全场景的越权挖掘

每个案例均按“场景→漏洞类型→漏洞分析→实战利用→修复方案”拆解,聚焦可复现的挖掘思路。

案例1:电商后台水平越权——篡改order_id遍历他人订单

场景

某电商平台“用户中心-我的订单”功能,用户登录后可查看自己的订单详情,请求URL为:https://xxx.com/api/order/getOrderDetail?orderId=123456

漏洞类型

水平越权(同权限普通用户间)

漏洞分析

后端仅校验“用户是否登录”(通过Cookie/Token判断),但未校验“请求的orderId是否属于当前登录用户”——攻击者只需篡改orderId(如123457、123458),即可遍历查看其他用户的订单(含收货地址、电话、支付金额)。

实战利用步骤
  1. 用自己的账号登录,打开“我的订单”,抓包获取查看订单的请求(Burp Suite拦截);
  2. 在Burp的“Repeater”模块中,修改orderId参数值(从123456改为123457),发送请求;
  3. 查看响应包,若返回“订单号123457的详情”(非自己的订单),则漏洞存在;
  4. 批量利用:用Burp的“Intruder”模块,设置orderId为数字递增(1-100000),自动遍历并提取含用户信息的订单数据。
修复方案

后端增加“资源归属校验”:查询orderId对应的订单时,强制关联当前登录用户的user_id(如SQL语句需包含where order_id=? and user_id=当前登录用户ID),非归属订单返回“无权限”。

案例2:CRM系统垂直越权——直接访问管理员报表URL

场景

某企业CRM系统,普通销售可访问https://xxx.com/sales/index,管理员可访问https://xxx.com/admin/report(查看全公司销售数据报表)。前端通过“隐藏管理员菜单”限制普通用户访问,但未在后端做权限控制。

漏洞类型

垂直越权(低权限→高权限)

漏洞分析

后端仅通过“URL路径”判断用户角色,未在/admin/report接口中校验“当前用户是否为管理员角色”——普通用户只要知道管理员URL,即可直接访问高权限功能。

实战利用步骤
  1. 用普通销售账号登录CRM,记录当前Cookie/Token;
  2. 在浏览器地址栏直接输入管理员报表URL:https://xxx.com/admin/report
  3. 若页面正常显示“全公司销售报表”(含其他销售的客户数据),则漏洞存在;
  4. 进一步测试:尝试访问/admin/userManage(用户管理)、/admin/roleEdit(角色修改),可能发现更多未授权功能。
修复方案

所有高权限URL/接口统一接入权限拦截器(如Spring Security的@PreAuthorize("hasRole('ADMIN')")),强制校验用户角色,非管理员直接返回403。

案例3:社交APP水平越权——篡改本地存储user_id查看他人私信

场景

某社交APP(Android版),用户查看私信时,APP本地缓存了当前用户的user_id=10086,请求私信列表的API为:POST /api/message/list,请求体中fromUserId=10086(默认读取本地缓存值)。

漏洞类型

水平越权(同权限用户间)

漏洞分析

后端未校验“fromUserId是否与当前登录用户的user_id一致”,仅依赖APP传递的fromUserId参数——攻击者可修改本地存储的user_id,或抓包篡改fromUserId,查看其他用户的私信。

实战利用步骤
  1. 用root手机安装APP,通过“MT管理器”找到APP的本地存储文件(如/data/data/com.xxx.app/shared_prefs/user_info.xml);
  2. 编辑文件,将user_id从10086改为目标用户ID(如10087),保存后重启APP;
  3. 打开“私信”功能,APP会自动用fromUserId=10087请求数据,若返回该用户的私信列表,则漏洞存在;
  4. 非root手机方案:用Burp Suite抓包,修改POST /api/message/list请求体中的fromUserId参数,同样可触发越权。
修复方案

后端从“会话凭证”(如JWT、服务器Session)中提取当前登录用户的user_id,而非依赖前端传递的fromUserId参数,彻底杜绝参数篡改。

案例4:云存储API水平越权——file_id遍历下载他人文件

场景

某云存储服务,用户上传文件后获得唯一file_id,下载URL为:https://xxx.com/download?fileId=abcdef123456&token=用户的下载凭证

漏洞类型

水平越权(同权限用户间)

漏洞分析

后端仅校验“token是否有效”(即是否为注册用户),但未校验“fileId对应的文件是否属于该token所属用户”——攻击者可生成随机file_id(如字母+数字组合),结合自己的有效token,遍历下载他人文件。

实战利用步骤
  1. 注册账号并上传1个文件,获取自己的tokenfile_id(如abcdef123456);
  2. 构造下载URL:https://xxx.com/download?fileId=abcdef123457&token=自己的token,用Burp发送请求;
  3. 若响应为“文件下载流”(非“无权限”或“文件不存在”),则漏洞存在;
  4. 批量利用:用Python脚本生成随机file_id(按云存储的file_id格式,如16位字母数字),循环拼接URL并请求,保存返回的有效文件。
修复方案

建立“file_id-user_id”关联表,下载时后端强制校验“当前token对应的user_id是否与file_id的归属user_id一致”。

案例5:管理系统垂直越权——篡改user_id修改管理员密码

场景

某后台管理系统,普通管理员可修改自己的密码,请求接口为:POST /api/user/resetPwd,请求体为:

{
  "userId": 1001,  // 普通管理员自己的ID
  "newPwd": "123456"
}
漏洞类型

垂直越权(低权限→高权限)

漏洞分析

后端仅校验“当前用户是否有权修改userId对应的账号”,但未校验“userId对应的账号角色”——普通管理员(角色ID=2)若将userId改为管理员账号(角色ID=1,userId=1000),即可重置管理员密码。

实战利用步骤
  1. 用普通管理员账号(userId=1001)登录,抓包获取“修改密码”的POST请求;
  2. 在Burp中修改请求体的userId为1000(假设管理员账号ID为1000),newPwd设为自己的密码;
  3. 发送请求,若返回“修改成功”,则用userId=1000和新密码尝试登录管理员后台;
  4. 若登录成功,说明已通过垂直越权获取管理员权限。
修复方案

修改密码时,后端不仅要校验“当前用户是否有权操作userId”,还要校验“userId的角色等级≤当前用户的角色等级”(如普通管理员无法操作管理员角色的账号)。

案例6:物流系统水平越权——未校验网点权限修改他人运单

场景

某物流系统,每个网点只能管理自己的运单(如修改运单状态为“已派送”),请求接口为:POST /api/waybill/updateStatus,请求体:

{
  "waybillId": 5678,
  "status": "DELIVERED",
  "branchId": 3  // 当前网点ID
}
漏洞类型

水平越权(同权限网点间)

漏洞分析

后端仅校验“branchId是否存在”,但未校验“waybillId对应的运单是否属于branchId所属网点”——网点A(branchId=3)可篡改waybillId为网点B的运单ID,修改其状态(如将“待派送”改为“已签收”),干扰正常业务。

实战利用步骤
  1. 用网点A的账号登录,获取1个自己的运单ID(如5678),抓包修改运单状态的请求;
  2. 从公开渠道(如物流查询页面)获取网点B的运单ID(如5679),在Burp中修改waybillId=5679,保持branchId=3
  3. 发送请求,若返回“修改成功”,则登录网点B账号查看该运单,确认状态已被篡改;
  4. 进一步测试:尝试将网点B的运单状态改为“已取消”,破坏其业务流程。
修复方案

建立“运单-网点”关联关系,修改运单状态时,后端强制校验“waybillId所属的网点ID是否等于请求中的branchId”。

案例7:SaaS平台垂直越权——篡改tenant_id访问其他租户数据

场景

某SaaS CRM(多租户模式),每个租户(企业)只能查看自己的客户数据,请求客户列表的API为:GET /api/customer/list?tenantId=202(当前租户ID),请求头携带Authorization: Bearer 租户用户的Token

漏洞类型

垂直越权(低权限租户→其他租户)

漏洞分析

后端仅校验“Token是否属于SaaS平台的合法用户”,但未校验“Token所属的租户ID是否与请求的tenantId一致”——租户A(tenantId=202)可篡改tenantId=203,访问租户B的客户数据(含联系方式、成交记录)。

实战利用步骤
  1. 用租户A的账号登录,抓包获取“客户列表”的GET请求;
  2. 在Burp中修改tenantId=203(可通过遍历1-1000获取其他租户ID),保持Authorization头不变;
  3. 发送请求,若返回租户B的客户列表,则漏洞存在;
  4. 进一步测试:尝试访问/api/tenant/finance(租户财务数据),篡改tenantId查看其他租户的营收数据。
修复方案

Token中解析出当前用户所属的tenantId(如JWT中包含tenantId字段),后端强制用解析出的tenantId查询数据,不接受前端传递的tenantId参数。

案例8:移动端APP垂直越权——JWT缺失角色校验访问管理员API

场景

某APP的API使用JWT认证,普通用户的JWT Payload为:{"userId": 10086, "exp": 1717248000},管理员API为POST /api/admin/deleteUser(删除用户)。

漏洞类型

垂直越权(普通用户→管理员)

漏洞分析

后端仅校验JWT的“有效性”(签名是否正确、是否过期),但未校验JWT中是否包含“管理员角色标识”(如role: "ADMIN")——普通用户只需用自己的JWT,直接调用管理员API,即可执行高权限操作。

实战利用步骤
  1. 用普通用户账号登录APP,抓包获取JWT(通常在Authorization头中);
  2. 用Postman构造管理员API请求:POST /api/admin/deleteUser,请求体{"userId": 10087}Authorization头为普通用户的JWT;
  3. 若返回“删除成功”,则漏洞存在(可登录其他账号确认用户10087已被删除);
  4. 进一步测试:调用/api/admin/addRole(添加角色),尝试给自己赋予管理员权限。
修复方案

JWT Payload中必须包含role字段(如"role": "USER""role": "ADMIN"),所有管理员API在后端强制校验role == "ADMIN",否则返回403。

案例9:支付系统垂直越权——普通用户调用商户结算接口

场景

某支付平台,商户可调用/api/merchant/settle接口申请结算(提现),普通用户(消费者)仅能调用/api/user/pay(支付)接口。

漏洞类型

垂直越权(普通用户→商户)

漏洞分析

后端通过“接口路径”模糊区分用户类型(/user/为普通用户,/merchant/为商户),但未在/merchant/settle接口中校验“当前用户是否为商户角色”——普通用户只需知道商户接口的参数格式,即可用自己的Token调用该接口。

实战利用步骤
  1. 注册普通用户账号,获取Token;
  2. 从支付平台的商户文档(或抓包商户测试环境)中,获取/api/merchant/settle的参数格式(如{"merchantId": 3001, "amount": 1000});
  3. 用普通用户的Token,构造请求调用/api/merchant/settle,尝试将merchantId改为任意存在的商户ID;
  4. 若返回“结算申请成功”,则漏洞存在(商户后台可查看该笔异常结算申请)。
修复方案

所有接口统一接入“角色拦截器”,根据用户Token中的角色标识(如userType: "MERCHANT"),判断是否有权访问对应接口,与接口路径无关。

案例10:CMS系统水平越权——编辑他人文章(未校验作者ID)

场景

某CMS系统(内容管理),作者可编辑自己发布的文章,编辑页面的请求为:POST /api/article/edit,请求体:

{
  "articleId": 789,
  "title": "修改后的标题",
  "content": "修改后的内容"
}
漏洞类型

水平越权(同权限作者间)

漏洞分析

后端仅校验“当前用户是否为作者角色”,但未校验“articleId对应的文章作者是否为当前用户”——作者A可篡改articleId为作者B的文章ID,修改其标题、内容(如植入广告、篡改观点)。

实战利用步骤
  1. 用作者A账号发布1篇文章,获取articleId=789,抓包编辑文章的请求;
  2. 在CMS的“文章列表”页面(公开可看),获取作者B的文章ID(如790);
  3. 在Burp中修改articleId=790,修改title为“测试越权编辑”,发送请求;
  4. 访问作者B的文章详情页,若标题已被改为“测试越权编辑”,则漏洞存在。
修复方案

编辑文章时,后端查询articleId对应的authorId,并与当前登录用户的userId对比,一致才允许编辑。

三、越权漏洞挖掘方法论:从“碰运气”到“系统化”

通过10个案例可提炼出越权挖掘的核心思路,帮你覆盖90%的越权场景:

1. 重点测试“用户资源类”功能

越权漏洞多存在于“与用户强关联的资源”中,优先测试以下功能:

  • 订单、账单、发票(财务相关);
  • 私信、评论、个人信息(隐私相关);
  • 文件上传/下载、文章、视频(内容相关);
  • 用户管理、角色修改、密码重置(权限相关)。

2. 参数篡改测试:锁定3类关键参数

所有用户可控的参数都可能是越权入口,重点篡改以下3类:

  • ID类参数user_idorder_idfile_idarticle_id(最常见,直接关联资源归属);
  • 权限标识参数roletenant_idbranch_id(关联权限等级或租户/网点);
  • 用户标识参数fromUserIdtargetUserId(前端传递的用户标识,优先篡改)。

3. 权限边界测试:低权限用户的“突破尝试”

  • URL遍历:收集高权限URL(如/admin//merchant/),用低权限账号直接访问;
  • API调用:获取高权限API的参数格式,用低权限Token调用;
  • 功能隐藏:查看前端源码(F12),寻找隐藏的高权限按钮/接口(如style="display:none"的管理员菜单),直接构造请求。

4. 会话与凭证测试:校验权限关联

  • JWT测试:解析JWT Payload,查看是否包含roleuser_id等权限信息,尝试修改后重新签名(或直接删除role字段);
  • Cookie测试:删除Cookie中的权限相关字段(如isAdmin),或修改其值(如0改为1),测试是否影响权限;
  • Token测试:用低权限Token调用高权限接口,测试是否仅校验Token有效性而忽略权限。

四、通用防御策略:从根源杜绝越权漏洞

越权漏洞的防御核心是“后端强制校验”,前端控制仅作为辅助,具体可落地为3条规则:

1. 所有资源访问必须“绑定当前用户”

  • 对用户专属资源(订单、私信、文件),查询时必须加入“当前登录用户ID”的条件(如SQL:where order_id=? and user_id=当前用户ID);
  • 禁止依赖前端传递的用户标识(如fromUserId),必须从会话凭证(JWT、Session)中提取当前用户ID。

2. 所有功能访问必须“校验权限等级”

  • 采用“角色-权限”矩阵(如RBAC模型),明确每个角色可访问的功能;
  • 所有接口/URL接入统一权限拦截器,强制校验用户角色,无权限直接返回403(而非跳转登录页)。

3. 会话凭证必须“包含权限信息并验证”

  • JWT/Cookie中必须包含roleuser_id等核心权限字段,且后端每次请求都需验证这些字段;
  • 禁止会话凭证仅验证“有效性”(如是否过期、签名是否正确),忽略权限关联。

五、总结:成为越权高手的3个关键

  1. 理解业务逻辑:越权漏洞本质是“权限与业务逻辑的不匹配”,只有理解“资源归属”“角色分工”,才能精准定位漏洞点(如电商的“订单归属用户”、SaaS的“租户数据隔离”);
  2. 坚持“后端不信任前端”:挖掘时假设“前端所有控制都是可绕过的”,重点测试后端是否有独立校验;
  3. 批量与自动化:对ID类参数(如order_idfile_id),用Burp Intruder或Python脚本批量测试,提升挖掘效率。

最后提醒:越权漏洞挖掘必须在授权环境下进行(如企业测试站、自己搭建的靶场),严禁未经授权测试生产系统,遵守《网络安全法》与道德规范。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐