是什么
IDOR(Insecure Direct Object Reference,不安全的直接对象引用):应用使用用户提供的输入直接访问对象,而没有做权限校验。
结果:用户可以访问本不属于自己的资源。
简单例子
一个查看订单的 API:
GET /api/orders/10086服务器返回订单 10086 的详情。
问题:服务器只根据 URL 中的 ID 返回数据,没有检查这个订单是否属于当前用户。
攻击:把 ID 改成 10087、10088……就能看到其他用户的订单(含姓名、地址、电话、购买内容)。
只是改一个数字——这就是 IDOR。
常见形式
一、数字 ID 递增:最容易发现和利用。
二、UUID/GUID:不那么容易猜测,但如果 UUID 在别处泄露(如共享的链接、日志),IDOR 依然存在。
IDOR 的本质是"缺少授权检查",与 ID 是否可猜测无关。
三、文件名/路径:
GET /download?file=report.pdf
GET /download?file=../../../etc/passwd(后者还涉及路径穿越。)
四、其他标识符:用户名、邮箱、手机号、订单号等。
与其它概念的关系
水平越权:同级别用户之间的越权(用户 A 看用户 B 的数据)。
垂直越权:低权限用户访问高权限功能(普通用户访问管理员接口)。
IDOR 通常指前者,但两者都是访问控制失效。
OWASP 将"访问控制失效"列为 Web 应用安全的顶级风险之一。
防御
一、在每个数据访问点做授权检查(根本)
原则:不信任任何来自客户端的标识符。
1. 从会话/令牌中获取当前用户 ID(**不能**从请求参数中获取)
2. 查询请求的订单
3. 检查 order.user_id == 当前用户 ID
4. 不匹配 → 返回 403 或 404注意:
- 当前用户的身份必须从服务端可信来源获取(session、签名 JWT),而不是请求参数中的
user_id=123; - 检查应该在数据访问层做,而不只是 UI 层(隐藏按钮不等于安全)。
二、使用不可猜测的标识符(缓解,非解决)
用 UUID 替代自增 ID 可以增加利用难度,但不能替代授权检查。
三、间接引用映射
为每个用户维护一个"用户特定的引用"到"真实对象"的映射。用户只能看到自己的映射。
这增加了一层防护,但实现更复杂。
四、集中式的访问控制
不要在成千上万个 API 端点中各自写检查——容易遗漏。
做法:在框架层面(中间件、装饰器、ORM 层)统一实施访问控制。
五、自动化测试
- 编写针对越权的测试用例:用用户 A 的凭据访问用户 B 的资源,应该失败;
- 在 CI 中运行;
- 渗透测试中专门覆盖这一项。
检测
手工测试:
- 用账号 A 登录,创建一个资源,记下其 ID;
- 用账号 B 登录,尝试访问该 ID;
- 如果能访问 → 存在 IDOR。
工具:Burp Suite 的 Autorize 插件等,可以自动化对比不同权限下的响应。
一个真实影响
IDOR 是最常见且危害直接的漏洞类型之一:
- 直接导致用户数据泄露(个人信息、支付记录、医疗数据);
- 利用门槛极低(改个数字就行)——自动化扫描器也能发现;
- 在 API 化的应用中尤其普遍。
它对开发者的提醒:"能找到资源"不等于"有权访问资源"。 每次返回数据前,都要问一句"这个人该看到这个吗?"
说明:本文为 Web 安全的知识整理。