文章总结: 本文介绍了水平越权(IDOR)的概念、原理、危害和检测方法,并通过实战案例说明其存在和防御策略。建议开发者在数据操作时进行强鉴权,避免暴露敏感关联参数,并采用UUID等规则来避免可预测的ID。
综合评分: 85
文章分类: 渗透测试,漏洞分析,安全建设,安全工具,安全开发
一篇文章讲清什么是水平越权(IDOR)
原创
小新
小新
小新的安全运营笔记
2026年9月24日 08:00
北京
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
你有没有想过这样一个问题:
当你登录办公系统看个人信息、或者在电商网站逛购物车时,为什么系统只会显示你的数据?有没有办法看到别人的信息?
正常情况下,一次数据请求应该是:
你的账号 → 发送数据 ID → 服务端校验权限 → 返回你的数据
大家看到的都应该是属于自己的信息。
但如果服务端在处理请求时,只检查了”你是谁”,却没有校验”你能不能看这条数据”,就可能出现一种非常经典且高危的逻辑漏洞:水平越权(Insecure Direct Object References,简称 IDOR)。
它不是传统意义上的”直接把服务器打崩”或”拿系统 Root 权限”,而是利用开发人员在编写业务逻辑时的疏忽,让普通用户通过简单篡改参数,偷偷”看”到或”改”到其他同级用户的数据。
听起来有点绕?我们用一个生活中的例子来理解。
一、先讲一个故事:同一张工资单,换个号码就能看
假设你去公司 HR 部门查询工资。HR 的规则是:
“每张工资单都有一个编号,你报出编号,我就拿给你。”
你登录公司工资系统,点击”查看个人工资详情”。这时你注意到,网页链接(URL)的结尾有一个数字 19(代表你的用户 ID):
http://localhost/salary/user/19
你心生好奇:如果我把地址栏里的 19 改成 18 会发生什么?
敲下回车后,屏幕上赫然出现了同事(派大星)的工资明细!
这就是水平越权的核心思路:攻击者(海绵宝宝)与受害者(派大星)拥有平级的系统权限(都是普通员工)。攻击者通过简单修改请求中的标识符(如 ID),就非法获取了同级其他用户的敏感数据。
如果有人写个自动化脚本从 1 遍历到 100000,全公司的工资数据就被一网打尽了。
二、水平越权到底在”越”什么权?
这里的”越权”,不是越级去操作管理员的功能(那是垂直越权),而是:在平级用户之间,越过数据的归属边界。
现代 Web 系统中,用户对数据的操作通常依赖于某种标识符(ID):
- 用户个人信息:
user_id=123 - 订单详情:
order_id=20260920001 - 敏感文件下载:
file_id=8899
当用户发起请求时:
浏览器 → API 网关 / 后端接口 → 数据库
问题就来了:后端服务器拿到这个 ID 后,到底有没有去验证”这个 ID 真的属于当前登录的用户”?
没有验证,或者验证逻辑有漏网之鱼,水平越权就产生了。
三、真实渗透实战场景复盘
在实际的安服和渗透测试项目中,水平越权往往隐藏在看似不起眼的业务逻辑中。
【实战案例】某景区官网系统的订单越权
最近在对某景区官网系统进行渗透测试时,系统提供了”游客登录”和”商户登录”两种模式。
进入商户后台后,页面包含了订单管理、门票核销等功能。抓包分析发现,商户查询门票列表的请求 URL 如下:
https://xxxx.com/list?ticket_id=1
当我尝试将 ticket_id 的值修改为其他数字时,系统毫无遮掩地返回了其他商户的门票销售记录与订单明细!
漏洞根源:后端接口在接收到参数后,直接拿着前端传来的 ticket_id 去数据库做了查询,却压根没有校验这个 ticket_id 的创建者是不是当前登录的商户。
四、核心困惑:为什么带了 Token,依然会发生水平越权?
这是很多初级安服工程师和开发人员最容易混淆的地方。
不少开发会问:”我们的系统明明使用了 JWT / Token 强鉴权,为什么还会被爆出水平越权?”
其实这是因为把”身份认证”与”数据授权”搞混了:
[ 用户请求 ]
↓
[ Token 校验 ] ──( 确认你是合法用户,身份为: User_A ) ──> ✅ 通过认证
↓
[ 业务数据查询 ] ──( 前端传参: order_id = 999 [属于 User_B] )
↓
❌ 后端未校验 order_id=999 是否属于 User_A,直接查库返回!
- Token(身份认证):仅解决了”你是谁”的问题(证明你已成功登录,令牌有效)。
- 数据校验(鉴权):解决的是”你能不能碰这条数据”的问题。
如果服务端仅在入口处校验了 Token 的有效性,而在后续的具体数据库 CRUD(增删改查)操作中,没有将 Token 解码出的当前用户 ID 带入查询条件,水平越权依然会畅通无阻。
五、水平越权的常见类型与危害
在测试中,不要以为水平越权只能”看”数据,它的危害取决于对应的业务接口:
1. 水平越权读取(数据泄露)
- 场景:查看他人订单、个人简历、工资单、私信记录。
- 危害:批量遍历导致海量用户隐私泄露。
2. 水平越权修改/删除(数据破坏)
- 场景:修改他人收货地址、重置他人账号绑定的邮箱/手机号、删除他人发表的文章。
- 危害:直接破坏其他用户的数据完整性,甚至导致批量接管账号(配合重置密码逻辑)。
3. 水平越权执行(高危业务操作)
- 场景:代替其他商户进行门票核销、用别人的账户余额进行下单消费。
- 危害:直接造成经济损失与业务逻辑紊乱。
六、测试人员应该怎么发现水平越权?
在实际渗透测试中,依靠纯手工修改参数效率较低,通常结合工具与逻辑推理:
1. 常用测试工具与技巧
- Burp Suite(Autorize 插件):自动化越权测试利器。配置两个不同权限账户(如 User A 和 User B)的 Cookie/Token,Autorize 会自动用 User A 的身份重放 User B 的所有请求,快速识别未鉴权接口。
- 抓包对比:重点观察 POST Body(JSON)、GET 参数、Header 参数中的 ID 类字段(如
userId、account、docId)。
2. 测试基本思路
准备两个同级测试账号 (User A / User B)
↓
用 User A 登录,触发敏感操作(如查询/修改订单)并抓包
↓
替换请求中的资源 ID 为 User B 的资源 ID
↓
保持 User A 的 Token/Cookie 不变,发送请求
↓
观察响应:若成功获取/修改了 User B 的数据 ➔ 存在水平越权!
⚠️ 安全测试注意事项:在生产环境或实战攻防测试中,切勿使用脚本进行无节制的 ID 自动化遍历。这样可能会误删、误改真实用户的生产数据,甚至引发合规事故。测试时应使用自己申请的两个测试账号进行交叉验证。
七、开发人员应该怎么防?
彻底防御水平越权,最核心的一句话是:永远不要相信前端传来的用户标识,所有数据操作必须在服务端进行硬性归属校验。
1. 实施基于服务端的强鉴权(带入绑定查询)
从服务端的 Session 或解密后的 Token 中获取当前登录用户的合法 ID,并作为数据库查询的必填条件:
-- ❌ 存在越权风险的写法(盲目信任前端传入的 ticket_id)
SELECT * FROM tickets WHERE ticket_id = input_ticket_id;
-- ✅ 安全的写法(强绑定当前登录商户的 ID)
SELECT * FROM tickets
WHERE ticket_id = input_ticket_id
AND merchant_id = current_user_id;
2. 资源标识符去规律化(UUID / 混淆)
避免在 URL 或接口参数中使用可被攻击者轻松推测的递增整型 ID(如 1, 2, 3)。改用无规律的 UUID 或强加密映射串,提高猜解难度。
3. 避免在前端暴露敏感关联参数
能从服务端上下文(Context/Session)直接获取的参数,就不要让前端显式传递。
八、给开发 / 测试的 Checklist
| 检查项 | 测试/开发重点 | 判断依据 |
| — | — | — |
| 参数提取 | 接口中是否包含 id、user_id、order_no 等资源标识符 | 任何可被篡改的业务 ID 均需列入风险排查范围 |
| 服务端鉴权 | 后端是否直接使用前端传入的 ID 查库,而未校验数据归属 | 未结合当前登录态 (Session/Token) 限制查询范围即存在风险 |
| Token 使用规范 | Token 是否仅作为”登录门禁”,而未带入具体数据操作流程 | Token 必须在接口层解析出用户身份并参与 SQL/逻辑判断 |
| 高危操作覆盖 | 修改密码、手机号绑定、数据删除等接口是否有平级交叉验证 | 避免跨用户修改或删除他人资源 |
| ID 规则设计 | 敏感资源 ID 是否采用了自增数字 | 建议使用 UUID 或无规律哈希串,阻断遍历猜解 |
| 工具自动化测试 | 是否使用 Burp Autorize 等工具对平级账号权限进行交叉替换测试 | 跨账号请求成功获取对方数据即判定为越权 |
九、最后总结
水平越权听起来很复杂,但核心其实只有一句话:后端接口只验证了”请求者已登录”,却省去了”校验请求者是否拥有该数据”的那一行代码。
整个漏洞逻辑可以简单理解成:
攻击者 (User A)
↓ 篡改请求中的资源 ID 为 User B 的数据 ID
前端发送请求
↓
后端服务器:"Token 是有效的,允许访问" (通过认证)
↓
后端数据库:"直接查 ID = User B 的数据并返回" (缺乏归属校验)
↓
产生越权数据泄露!
所以,在进行安全服务、渗透测试或代码审计时,不要只盯着高深莫测的复杂漏洞。
越权大多只是开发时省略了一行归属判断。而安全的关键,就是让服务端的每一行数据查询,都牢牢守住权限的边界。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:小新的安全运营笔记 小新
小新《一篇文章讲清什么是水平越权(IDOR)》