首页/安全/漏洞与攻击面速查/越权访问(IDOR)原理与防护
Web 漏洞原理与防护55 条

越权访问(IDOR)原理与防护

IDOR 指接口用直接对象标识(如 order_id=123)查询数据但不校验归属,导致水平越权读取或修改他人数据;防护原则是每个数据访问都做主体与资源的归属校验。

漏洞与攻击面速查安全更新于 2026-10-13

越权访问是什么

越权访问指系统只验证了「你已登录」,却没有验证「这条数据是否属于你」。接口用订单号、文件 ID 这类直接对象标识查询数据,服务端不校验归属,攻击者把标识换成别人的值就能读到或改到他人数据,这类问题通常称为 IDOR(不安全的直接对象引用)。另一种形态是垂直越权:普通用户能访问管理员功能,成因是权限判断只做在前端菜单或网关层。它的特点是数量密集、发现容易,一旦存在往往整站同类接口都有。

基本信息

风险类别OWASP Top 10 2021 A01 失效的访问控制;CWE-639
主要形态水平越权(同角色跨用户)与垂直越权(低权限访问高权限功能)
成因只校验登录态不校验归属,信任前端传入的身份或权限字段
常见位置详情与下载接口、批量接口、导出接口、GraphQL 节点查询
危害批量读取他人数据、篡改与删除他人数据、越权执行管理操作
修复要点服务端强制归属校验,查询条件带当前主体,权限判断不可下放前端

常见出问题的地方

  • 订单、工单、发票的详情与下载接口,按 ID 直接查询
  • 用户资料与地址的修改接口,只校验登录不校验归属
  • 文件与附件下载,路径或文件 ID 可枚举
  • 批量操作与批量导出,循环里逐条查询但不做归属过滤
  • 管理功能接口挂在普通用户可访问的路由下,仅前端隐藏入口
  • GraphQL 或开放 API 通过节点 ID 查询,授权逻辑分散在各解析器中
  • 第三方回调与消息队列消费接口,按消息中的 ID 直接落库

风险与修复对比

风险与修复对比
风险:/api/orders/12345 仅按 id 查询,未校验归属
修复:查询条件强制带归属:
SELECT * FROM orders WHERE id = ? AND user_id = ?
或在访问前显式执行权限判断
# Java 示例:Order o = repo.findByIdAndUserId(id, currentUserId)
# 中间件示例:统一在路由层绑定当前主体,禁止直接用前端传的 userId
# 关键原则:授权判断放在服务端数据访问路径上,而不是页面渲染时

排查清单

排查清单
遍历接口中的资源 ID 参数(订单、发票、文件、地址…)
确认每个读写点都有归属校验
批量接口、导出接口同样覆盖
越权测试:用 A 账号访问 B 账号资源(授权测试范围内)
检查参数里是否出现 userId、role、tenantId 等可篡改的身份字段
检查返回对象是否包含不该看到的字段(脱敏与最小化返回)

两种越权形态对照

形态表现验证方式
水平越权同角色读取或修改他人数据用 A 账号请求 B 账号的资源 ID
垂直越权低权限角色可调管理接口用普通账号直接请求管理端接口
混合形态先越权拿到管理员 ID 再读其数据组合多步请求验证数据边界
前端隐藏入口不构成防护:直接请求接口即可绕过,权限判断必须在服务端完成。
换成 UUID 或加密 ID 只是提高猜测难度,属于缓解手段;缺少归属校验时,任何 ID 形式都挡不住越权,且标识一旦从日志或分享链接泄露就会失效。

易错点

  • 只防读不防写:修改与删除接口的越权后果更严重,要逐个确认
  • 认为换成 UUID 就安全:缺归属校验时任何 ID 形式都挡不住越权
  • 信任前端传来的 userId 或 role 字段:应完全忽略客户端身份参数,以服务端会话为准
  • 只修被通报的那一个接口:同类接口往往是同一套模板生成的,要按参数模式全量排查
  • 批量与导出接口遗漏:循环查询时如果不带归属条件,一次请求就能拉走大量他人数据
  • 返回字段过大造成越权式泄露:即使归属正确,也要按角色最小化返回字段

数据来源与参考

  • OWASP Top 10 A01(失效的访问控制)
  • OWASP WSTG IDOR 测试章节
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌