一篇文章讲清什么是水平越权(IDOR)

admin 2026-09-29 05:44:33 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍了水平越权(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)》

评论:0   参与:  0