三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

IDOR 不安全的直接对象引用:API 越权实战检测

IDOR 不安全的直接对象引用:API 越权实战检测

API 越权里,出镜率最高的名字之一叫IDOR(Insecure Direct Object Reference,不安全的直接对象引用)。名字有点学院派,翻译成人话却很土:

你拿着自己的登录态,把请求里的“对象编号”改成别人的,服务器居然把别人的东西给你了。

订单号、用户 ID、文件 ID、商户 ID、工单号、uuid看起来很随机……只要服务端没有认真问“这个对象属于你吗”,改编号就可能得手。扫描器对这类洞经常哑巴——它不懂“10086 是你的、10087 是他的”。所以 IDOR 几乎成了人工测试与业务安全的自留地。


一、IDOR 到底在说哪一种越权

1. 经典定义

应用使用用户可控的标识(ID)直接访问对象,却缺少或失败于授权校验,导致访问了未授权对象。

“直接对象引用”可以是:

  • 数字 ID:/orders/1024
  • UUID:/files/550e8400-e29b-41d4-a716-446655440000
  • 文件名:/download?name=contract.pdf
  • 预签名 URL 中的路径参数(若权限模型错误)
  • GraphQL 的id参数

UUID降低枚举,不自动消灭 IDOR——你若仍能通过泄漏的 UUID 访问他人对象,那仍是授权失败,只是攻击面从“遍历”变成“泄露后利用”。

2. 水平 vs 垂直

类型含义例子
水平越权同级用户互访对方资源A 看 B 的订单
垂直越权低角色访问高角色能力/资源普通用户调管理删除
未授权没登录也能访问游客看需登录数据

IDOR 最常指水平对象级越权;广义报告里也有人把“改 role 参数”写成 IDOR,更严谨应写垂直越权/失效访问控制。检测手法高度重叠,定性时尽量准确。

3. 和“失效的访问控制”的关系

OWASP A01 大类下,IDOR 是最具体、最好教的一种。修好 IDOR,不等于访问控制满分,但能消掉一大片真实事故。


二、为什么 API 是重灾区

1. 前后端分离

前端不展示的按钮,API 依然在。移动端、小程序、第三方还共用一套后端。攻击者直接打 API,不走你的页面流程。

2. 对象 ID 满天飞

REST 风格天然/resource/{id}。列表接口先返回一堆 ID,详情接口再按 ID 取——若详情只验登录,IDOR 就成了“列表当字典 + 详情当仓库”。

3. 微服务与网关

网关验了 JWT,下游服务以为“网关都验了就信任”,只按 ID 查库。身份传到了,授权没传到。

4. 批量与导出

/orders?ids=1,2,3、导出任务、消息推送预览——一次越权一片数据。

5. 非 JSON 的“旁路对象”

PDF、发票、附件下载、WebSocket 订阅频道名、对象存储 key——都是对象引用,都要鉴权。


三、实战检测总流程(建议背下来)

① 准备账号矩阵(A/B,必要时商户/管理员) ② 摸清对象与 ID 出现位置(列表、推送、导出) ③ 对每个“带 ID 的读/写/删”做换绑测试 ④ 扩大到批量、导出、下载、共享链接 ⑤ 记录证据、定级、清理、回归用例化

核心动作就一个字:——换 ID、换账号、换角色、换租户。


四、账号与环境准备

1. 至少两套同级账号

A、B 权限相同,数据隔离。分别制造自己的订单/文档/消息。
记下:A 的order_id、B 的order_id

2. 再加角色更好

普通用户、商户、运营、管理员——垂直问题一起捞。

3. 租户/组织

SaaS 多租户测org_idtenant_id是否可改。这是 IDOR 的亲戚,常叫跨租户越权。

4. 工具

代理(Burp 等)、两个浏览器配置、可选的自动化脚本(只在授权范围)。
别对生产狂暴遍历 ID,以免触发风控或造成数据压力。


五、发现“对象引用”的实战技巧

1. 从列表到详情

登录 A,打开列表,抓详情请求。所有像 ID 的参数列成表:路径参数、Query、Body、Header(少见但有)。

2. 从 JS 与 APP 里挖隐藏 API

前端路由、Webpack 里的/api/、旧版接口。隐藏的getUserById往往鉴权更嫩。

3. 从通知与邮件挖 ID

邮件链接、短信链接、推送 deep link 带长 ID——测这些 ID 是否可在未分享情形下被他人使用。

4. 上传与下载

上传返回fileId,下载GET /file/{fileId}。用 B 的 token 下 A 的 fileId。

5. GraphQL / RPC

query { order(id: ...) { ... } }
mutation 里的 id。GraphQL 一次查询多字段,越权危害更大,检测逻辑一样:换 id + 换身份。


六、检测动作详解

1. 水平读越权(最常见)

  • A 登录,访问 A 对象,存响应指纹(姓名、金额、标题);
  • 同一请求,把 ID 改成 B 的,仍用 A 的 Token;
  • 若返回 B 的指纹 → 读 IDOR 成立。

注意:有的返回 200 但空数据/统一报错,要区分“无权限”和“对象不存在”。以敏感字段是否出现为准。

2. 水平写越权

改地址、改订单备注、取消订单、修改共享权限。
用 A 的身份提交 B 的 ID。写成功比读成功更严重。

3. 删除与状态变更

删除别人的评论、归档别人的项目。状态机类操作都要测。

4. 创建时指定他人 ID

创建订单时 body 带userId;创建子账号时指定orgId。属“引用绑定越权”。

5. 批量接口

ids[]=B的iduser_ids列表。部分成功也要报。

6. 函数级:导出与异步任务

创建导出任务时带筛选条件,任务结果是否可被另一用户的task_id下载。
异步世界的 IDOR:task_idjob_idreport_id

7. 存储与 CDN

返回的 URL 是否永久有效、是否无额外鉴权、是否可猜。
预签名过期短、且绑定权限,才有意义。

8. 编码与间接引用

ID 经 Base64、加密——若可解密或可替换密文仍过,继续测。
“加密 ID”不是授权。


七、自动化检测:能做多少、不能指望多少

1. 半自动

插件协助替换 ID、对比响应相似度,能提速。仍需人定义“哪些是对象”。

2. 基于流量的差分

用 A、B 账号分别爬业务,自动尝试交叉 ID。对标准化 REST 有效,对复杂业务易误报漏报。

3. 为什么很难全自动

  • 不知道“同级对象”集合;
  • 不知道响应里哪段算敏感成功;
  • 验证码、验证码、步骤码打断;
  • 合法共享会导致误报(A 本就可看 B)。

结论:IDOR 检测以方法论固化的人工/半人工为主,自动化是帮手。


八、合成案例集(方便内训)

案例 1:医保/电商订单详情 IDOR,泄露地址电话。
案例 2:工单系统附件fileId可跨员工下载。
案例 3:多租户 SaaS 改tenant_id读他租户报表。
案例 4:GraphQLuser(id)无授权指令。
案例 5:导出任务 ID 可枚举下载。
案例 6:对象存储 key 来自接口,下载接口未二次鉴权。
案例 7:“分享链接”永久有效且无密码,等于公开 IDOR。
案例 8:修改收货地址接口可改他人address_id

每个案例的检测动作都是:双账号 + 换引用 + 看是否成功。


九、定级建议

情况级别参考
可读大量 PII / 证件 / 订单高危~严重
可写/删除他人关键对象严重
跨租户数据严重
仅可读非敏感公开类对象中低(视业务)
需先获取机密 UUID 且难泄漏仍要修,可注明利用条件

“ID 难猜”不能当作接受风险的唯一理由,尤其当 ID 会在列表、日志、推送、Referer 里泄漏时。


十、修复与架构级解法

1. 服务端强制鉴权(根治)

伪代码思维:

obj = load(id) if obj.owner != current_user and not has_perm(...): deny

每个对象类型集中写策略,避免每个 Controller 手写漏掉。

2. 统一授权中间件 / 策略引擎

基于注解:@PreAuthorize、自定义checkOrderAccess(orderId)
GraphQL 字段解析器同样要挂授权。

3. 避免可信客户端

不要信 body 里的userId当所有者;所有者取自会话。

4. 间接引用可作辅助

每用户映射表、短时 tokenized reference——减枚举。仍需鉴权。

5. 批量接口

逐个做授权过滤;无权的 ID 不返回、不计入。

6. 下载与文件

鉴权后流式输出;或短时预签名且绑定用户与对象。

7. 多租户

所有查询带tenant_id = current_tenant强制条件(行级安全),禁止客户端传租户覆盖。

8. 日志与监控

授权失败告警;异常批量 403/交叉访问模式。

9. 测试门禁

CI 中集成双账号 API 测试:A token + B id → expect 403。
这是防回归最有效的手段。


十一、检测工作检查单(可直接贴到项目)

准备

  • A/B 账号与各自对象 ID
  • 代理可改包
  • 范围与生产安全阀

覆盖

  • 详情读
  • 更新/删除
  • 批量
  • 导出/异步任务
  • 附件下载
  • GraphQL/RPC
  • 租户字段
  • 分享链接

证据

  • 请求/响应(脱敏)
  • 两个账号对比
  • 复现步骤

收尾

  • 通知开发
  • 补回归用例
  • 复测关闭

十二、常见翻车与误报

误报:家庭共享、企业委托、医生看病人——本身有授权关系。要先懂业务。
漏报:只测了读,没测写;只测了 REST,没测下载;只测了数字 ID,没测任务 ID。
假修复:前端隐藏 ID;改成 UUID 但仍不鉴权;仅网关验登录。
假安全:“我们 ID 是加密的”。


十三、收尾

IDOR 的检测没有神秘公式,只有重复一千次仍然有效的动作:

用自己的身份,访问别人的对象引用。

API 让这个动作更简单,也让疏漏更致命。防住它也不靠改成 UUID 的心理安慰,而靠每一条对象访问链路上的强制授权,以及双账号回归测试这道门禁。

今晚若只做一件事:选一个最核心的详情 API,准备两个账号各造一条数据,把 A 的 token 配上 B 的 id 打一次。
200 且是 B 的数据——恭喜你挖到了真洞;403——恭喜你们对象鉴权可能真的在线。无论哪种,你都已经在做“API 越权实战检测”,而不是在背 IDOR 的英文全称。


附:快速对照

问题检测动作修复
水平读A token + B id对象级鉴权
水平写A token 改 B 对象同上 + 审计
批量混入他人 id逐条过滤
下载换 fileId鉴权后输出
租户改 tenant_id强制租户条件
← 返回列表