授权渗透测试 IDOR 核验教程:从对象标识枚举到越权证据与整改复测

枫少@KillBoy
枫少@KillBoy
枫少@KillBoy
管理员
399
文章
0
粉丝
渗透测试1 21字数 3377阅读11分15秒阅读模式
AI智能摘要
“能取到别人的数据”就是漏洞?IDOR 核验真正的难点不是枚举多少对象标识,而是在开始前就想清楚:在 A 账号上下文中取回 B 的对象,究竟是对象级授权缺失,还是该资源本就设计为共享?忽略“这次要证明什么”,后续对照与证据就会沦为无法复核的抓包展示。如何用双账户最小对照与可控停止条件,构建能写进报告的判断依据?
— AI 生成的文章内容摘要

核验 IDOR 的第一步,是在测试计划里明确写下“这次要证明什么、在哪些对象上证明、证明到什么程度就停”。IDOR(Insecure Direct Object Reference,不安全对象直接引用)在概念上常被归入访问控制缺陷,但真正决定核验质量的是资源归属判断:一个对象标识在另一账号上下文中被取回,究竟说明对象级授权缺失,还是该资源本来就被设计为共享?只要这个问题没有在开始前想清楚,后续的对照、枚举和证据记录都会变成无法复核的“抓包展示”。

本文面向已获得书面授权、正在做 Web 与 API 访问控制评估的渗透测试人员和安全评估团队,使用两个可控测试账户与自建测试数据,在明确的对象范围内演示如何设计最小化用例、控制请求频率、记录账号上下文和响应证据,并给出可写入报告的复现条件、风险判断和整改后回归方法。所有示例域名、账号和对象标识均为占位值,测试对象仅限授权确认书或测试方案中列出的端点与数据范围。

双账户对照与授权测试范围的渗透测试工作台示意

授权与前置条件:先确认边界,再谈验证

在动任何请求之前,需要确认以下条件全部满足,否则应停止测试并向授权方澄清:

  • 书面授权范围列明了目标域名、API 根路径、允许测试的角色和禁止访问的路径(如支付、生产导出接口)。
  • 至少准备两个测试账号 A 和 B,二者属于同一权限体系但归属不同主体,或者属于两个独立租户。
  • 每个账号下存在由该账号自行创建的测试对象,例如文档、工单、订单、发票、上传文件,且这些对象在授权数据范围内。
  • 测试对象的标识符与真实用户数据可清晰区分,例如使用专门的测试前缀或测试环境中的编号。
  • 请求频率、并发数和单次核验的数据量已在测试方案中约定,并且有明确的中止联系人。

OWASP Cheat Sheet 对 IDOR 的验证方式给出了很直接的起点:创建 A、B 两个用户,分别为各自创建对象,然后以 A 的身份修改对象引用访问 B 的对象,检查应用是否拒绝未授权访问。这个设计看起来简单,但如果没有前置条件约束,测试者很容易在验证过程中把“能取到别人的数据”当作漏洞证据,而忽略动作本身是否在授权范围内。这个边界一旦越过,取证就不再服务于评估,反而会扩大测试影响。

侦察与假设:识别对象引用与归属关系

侦察阶段的目标不是“把所有 id 都试一遍”,而是识别哪些参数真正承载对象引用,以及这些对象在业务上归谁所有。重点观察以下几类位置:

  • 路径中的资源标识,如 /api/invoices/{invoice_id}、/files/{file_id}。
  • 查询参数或 JSON 体中的对象键,如 id、userId、account、tenant_id。
  • 客户端 JavaScript 中调用 API 的位置,用来发现文档或页面未直接暴露的端点。
  • 静态资源引用,如发票 PDF、上传附件的下载路径。
  • 自定义请求头中不被文档描述的标识字段。

侦察时只做只读观察和少量一次性的请求记录,不进行批量枚举。判定一个参数是否值得进入验证阶段,可以先用“归属假设”来描述,例如:“GET /api/documents/{doc_id} 返回的对象字段中包含 owner_id,可以据此判断资源归属;根据页面表现推测后端仅按对象标识查询,未附加当前账号过滤。”假设需要写明预期结果和否证条件,否则后续无法区分“验证到真实缺陷”和“验证到一个共享功能”。

双账户对照设计:用最小用例替代批量枚举

双账户对照的核心是保持请求几乎相同,只替换能体现对象归属的上下文。以下是经过裁剪的最小流程,所有编号均为占位值:

  1. 以账号 A 登录,创建两条自建对象:doc-A-001 和 doc-A-002,记录返回体的对象标识、归属字段、创建时间。
  2. 以账号 A 的身份请求 doc-A-001,保存完整请求与响应,作为基线。
  3. 以账号 A 的身份请求同一接口、把标识改为账号 B 的自建对象标识 doc-B-001,观察状态码、响应体结构和字段内容。
  4. 若返回内容属于 B 且不包含可用于公开共享的标记,记录为候选缺陷;若返回 403、404 或空结果,记录为拒绝。
  5. 对读写操作分层验证:先只读,再考虑在有明确要求且授权允许时验证写操作;删除、批量导出和管理操作默认不在最小用例中。

这里有一个容易忽略的细节:同一账号内的对象对照同样重要。对 A 请求 doc-A-002 应成功,对 A 请求 doc-B-001 应失败,两条结果共同支撑“对象级授权确实存在”。如果两条都成功,说明可能存在预期共享或对象确实属于 A,需要先回到归属关系上排查,而不是立刻下结论。

响应码不足以判定对象级授权。更可靠的证据包括响应体中对象归属字段、ETag 或版本信息、字段结构是否返回真实内容,以及错误信息是否泄露对象是否存在。这些字段才是报告里能站得住脚的判断依据。

枚举范围与停止条件:把力用在证明归属上

在授权测试中,枚举应当服务于“补充归属证据”,而不是寻找更多可拉取的数据。控制手段可以按以下方式落实:

控制点做法停止条件
枚举范围仅使用已列明的测试对象标识,或按方案约定的少量相邻编号超出方案规定的数量后停止
请求频率单线程或低并发,按方案约定间隔发送达到约定请求数或触发监控阈值时停止
数据保存仅在本地保存响应摘要与证据字段,不保留真实个人数据全文一旦发现响应含真实用户数据即停止并上报
越界发现若返回对象明显不属于测试数据集立即停止,不再继续枚举
写操作默认不做;如授权明确要求,先验证回滚方案无回滚路径时不执行写操作

一个实用的停止规则是:如果一轮对照已经能稳定证明或否证对象级授权,就不需要继续扩大枚举。报告读者关心的是判断依据是否清楚,而不是测试者试了多少个标识。对于含可预测数字标识的端点,验证“可预测”本身不构成结论,仍要回到归属和授权判断上。

IDOR 授权核验中的对象标识与请求证据记录表

证据记录:让复现条件可被复核

每条候选缺陷应至少包含以下字段,便于开发人员和复测人员复核:

  • 测试账号 A 与 B 的标识,以及二者之间的关系(不同用户、不同租户或不同角色)。
  • 对象标识、创建方式、归属字段,以及对象是否在授权范围内。
  • 完整请求上下文:方法、路径、关键请求头、参数名与占位值。
  • 基线请求和对照请求的状态码、响应字段结构和判断依据。
  • 时间、请求频率、是否触发监控或告警,以及测试中是否发生任何写操作。
  • 停止原因,例如“验证完成即停止”“出现非测试数据后终止”。
  • 复现步骤与复现条件,避免只贴截图。

记录中不应保留真实用户的姓名、手机号、地址或可组合识别个人的字段。如果响应中出现了这类信息,正确做法是立即停止测试、上报给授权方,并把证据摘要中相关字段替换为脱敏占位值。

风险判断:区分预期共享与真实对象级授权缺陷

同样一个“能取到另一账号对象”的结果,可能对应完全不同的结论。以下几种情况需要分别处理:

  • 预期共享:对象的归属关系本身就是多对多,例如已授权协作的文档、团队共享工单、公开下载资源。判断依据是返回体或业务说明中是否存在共享关系、成员列表或显式公开标记。
  • 认证缺失:未登录即可访问,或仅凭会话令牌访问本账号自己的对象,不属于 IDOR 的核心场景,应作为另一类问题记录。
  • 会话绑定:资源由当前会话令牌绑定,不以客户端传入的标识选择对象,此类情况不构成 IDOR。
  • 真实对象级授权缺陷:在 A 的上下文中取回仅属于 B 的对象,且返回了 B 的真实字段内容,同时不存在共享关系。此时风险等级取决于对象类型:只读资金、发票、个人资料等通常风险高于低敏感度的公开资源。
  • 敏感度与影响需要写清:是否可批量、是否涉及写操作、是否有审计日志、是否可进一步访问关联资源。

OWASP 的建议中强调,无论对象标识是否可预测或难以猜测,都应在所有涉及对象引用的操作上验证访问控制,包括读取、创建、更新、删除、导出和管理动作。这一点在风险判断时同样适用:验证重点不是“猜到了别人的 ID”,而是“对应操作是否做了对象级授权”。

修复建议:从服务端对象级授权入手

修复建议应围绕服务端对象级授权展开,而不是只做标识混淆或前端隐藏:

  • 在服务端对每个对象读取或变更操作执行归属校验,确认当前主体对目标对象具备授权,而不是只校验登录状态。
  • 对列表和检索接口同样校验,防止通过查询参数间接取到未授权对象。
  • 对导出、批量操作和管理动作使用统一的授权判断路径,避免部分端点遗漏。
  • 返回结构收敛,错误信息区分“不存在”和“无权限”时谨慎泄露对象是否存在。
  • 对无法使用服务端会话绑定的场景,建立可审计的共享关系模型,明确共享与授权是两件事。
  • 增加针对对象级授权的自动化回归用例,覆盖读取、写入和删除。

修复不应被替换为单纯使用不可猜测的 UUID 或随机标识。标识复杂度只能提高猜测成本,无法替代对象级授权;一旦标识通过日志、链接或接口返回泄露,授权缺失仍然会暴露对象。

回归复测:用同一套对照条件验证修复

复测的重点是条件一致:账号、对象、请求路径和判断依据与初测保持对应,否则无法确认修复有效。

  • 使用与初测相同的 A、B 账号关系和自建测试对象。
  • 重放基线请求,确认授权用户对自有对象仍能正常访问,避免修复导致合法功能中断。
  • 重放对照请求,确认跨账号访问返回拒绝,并且响应中不再出现他人的真实内容。
  • 检查写操作与批量操作是否同样受控,未在初测中验证的动作可在授权补充后复查。
  • 检查错误信息和审计日志,确认拒绝结果可被识别和记录。
  • 若修复引入共享模型或新端点,针对新端点补充最小对照用例。
  • 在报告中写明修复前后条件差异、复测结论和仍存在的残余风险。

报告落地:把核验过程写成可执行结论

一份经得起复核的 IDOR 核验记录,通常包括测试范围与授权依据、账户和对象说明、基线对照结果、判断依据、停止条件、影响范围、修复建议和回归复测结论。叙述时尽量使用“在账号 A 上下文请求账号 B 的自建对象,返回状态码与响应字段显示……”这类具体事实,而不是“已拿下”“任意用户数据可读”这类难以复核的概括。对测试中任何触及真实数据的迹象,保留停止与上报记录,这本身就是评估过程的一部分。

 
枫少@KillBoy
    • 灵巧的松鼠
      灵巧的松鼠 1

      IDOR的归属判断确实容易混淆

    匿名

    发表评论

    匿名网友

    拖动滑块以完成验证