第 6 章 · 03 IDOR 与越权(对象级 / 功能级 / 批量赋值)


文档摘要

第 6 章 · 03 IDOR 与越权(对象级 / 功能级 / 批量赋值) 本节摘要:访问控制漏洞不靠花哨 payload,靠的是「我能不能做本不该做的事」。本节把三类最常见的越权合并讲解:IDOR/BOLA(对象级授权失败)——把别人的对象 ID 换进请求就拿到/改了别人的数据;BFLA(功能级授权失败)——低权限者调用了本该只有管理员能调的端点/动作;Mass Assignment(批量赋值)——服务器把客户端提交的字段直接绑进模型/DTO,没有字段级白名单,导致 / / 被悄悄改写。

第 6 章 · 03 IDOR 与越权(对象级 / 功能级 / 批量赋值)

本节摘要:访问控制漏洞不靠花哨 payload,靠的是「我能不能做本不该做的事」。本节把三类最常见的越权合并讲解:IDOR/BOLA(对象级授权失败)——把别人的对象 ID 换进请求就拿到/改了别人的数据;BFLA(功能级授权失败)——低权限者调用了本该只有管理员能调的端点/动作;Mass Assignment(批量赋值)——服务器把客户端提交的字段直接绑进模型/DTO,没有字段级白名单,导致 role/isAdmin/ownerId 被悄悄改写。三者共享同一套方法论:构建「主体 × 对象 × 动作」或「主体 × 动作」矩阵,至少两个身份(owner 与非 owner、basic 与 admin),在每一条传输通道(REST/GraphQL/gRPC/WebSocket)、每一种编码(JSON/form/multipart)上交叉验证授权是否一致。授权必须在「执行动作的服务边界」上,把主体、动作、具体对象三者绑定到每一次请求——UI 门槛、网关、先前步骤都不能替代。

内容来源:原项目知识包 strix/skills/vulnerabilities/{idor,broken_function_level_authorization,mass_assignment}.md,汉化并套用体系化模板合并。

⚠️ 仅限授权测试:本节所有 payload 与技术仅用于你自己的应用或有书面授权的渗透测试。未经授权对他人系统使用这些技术是非法的。

学习目标

阅读完本节,你应当能够:

  1. 区分三类越权——对象级(IDOR/BOLA)、功能级(BFLA)、字段级(Mass Assignment)——的本质与攻击面差异。
  2. 识别对象引用的位置与形态(路径/查询/body/header/cookie、JWT claim、GraphQL 参数、整数/UUID/复合键/不透明 token)。
  3. 完成 IDOR 的枚举技巧(类型/边界值/重复键/大小写别名/二级 IDOR)与 BFLA 的动作面侦察(动词漂移、边缘 vs 核心、特性开关、批处理路径)。
  4. 构建 Mass Assignment 的敏感字段字典(role/isAdmin/ownerId/plan/限额/特性开关/计费)。
  5. 在多种传输通道与编码下交叉验证授权一致性,识别解析器/网关/缓存差异。
  6. 用验证步骤确认漏洞、排除误报
  7. 评估三类越权的影响等级并完成链式攻击(IDOR+CSRF、IDOR+Stored XSS、IDOR+SSRF、IDOR+Race)。

一、攻击面

三类越权的攻击面各有侧重,但都围绕「引用/动作/字段未被绑定到调用方」。

1.1 对象级(IDOR / BOLA)

作用域:

  • 横向:访问另一个主体同类型的对象。
  • 纵向:访问特权对象/动作(仅管理员/员工)。
  • 跨租户:打破多租户系统的隔离边界。
  • 跨服务:token 或上下文被错误的服务接受。

引用位置:路径、查询参数、JSON body、form-data、header、cookie;JWT claim、GraphQL 参数、WebSocket 消息、gRPC 消息。

标识符形态:整数、UUID/ULID/CUID、Snowflake、slug;复合键(如 {orgId}:{userId});不透明 token、base64/hex 编码 blob。

关系引用:parentIdownerIdaccountIdtenantIdorganizationteamIdprojectIdsubscriptionId

展开/投影开关:fieldsincludeexpandprojectionwithselectpopulate——常在 resolver/serializer 里绕过授权

高价值对象:导出/备份/报表端点(CSV/PDF/ZIP)、消息/邮箱/通知/审计日志/动态流、计费(发票/支付方式/交易/信用)、医疗/教育/HR/PII/PHI/PCI、管理员/员工工具与模拟、对象存储 key(S3/GCS 签名 URL、分享链接)、后台任务(导入/导出 job ID、任务结果)、多租户资源。

1.2 功能级(BFLA)

核心:调用方能调用本无权调用的函数/动作(端点、mutation、管理员工具)。常见于「不同传输/网关/角色之间校验不一致」或「服务信任客户端提示」。

  • 纵向授权:普通用户可触达特权/管理员/员工动作。
  • 特性门槛:在边缘/UI 强制,核心服务没有。
  • 传输漂移:REST vs GraphQL vs gRPC vs WebSocket 校验不一致。
  • 网关信任:后端信任代理/边缘注入的 X-User-Id/X-Role
  • 后台 worker/job:执行动作时不复查授权。

高价值动作:角色/权限变更、模拟/sudo、邀请/接受加入组织;审批/作废/退款/发信用、价格/套餐覆写;导出/报表生成、数据删除、账户停用/激活;特性开关切换、配额/授权调整、许可证/席位变更;2FA 重置、邮箱/手机号验证覆写。

1.3 字段级(Mass Assignment)

核心:客户端提交的字段被直接绑进模型/DTO,没有字段级白名单。常见于现代 API 与 GraphQL,导致提权、所有权变更、非授权状态转换。

  • 绑定面:REST/JSON、GraphQL input、form-encoded 与 multipart body;控制器/resolver 的模型绑定;ORM 的 create/update 助手;可写的嵌套关系、稀疏/patch 更新、批量端点。
  • 敏感字段族:扁平字段(isAdmin/role/roles[]/permissions[]/status/plan/tier/premium/verified/emailVerified)、所有权/租户(userId/ownerId/accountId/organizationId/tenantId/workspaceId)、限额/配额(usageLimit/seatCount/maxProjects/creditBalance)、特性开关(features/flags/betaAccess/allowImpersonation)、计费(price/amount/currency/prorate/nextInvoice/trialEnd)。

💡 核心心法:授权必须在执行动作的服务边界,把主体、动作、对象(以及字段)绑定到每一次请求。引用是否不透明(UUID)无关紧要——拿到就能测;UI 门槛、网关、先前步骤都不能替代服务自身的检查。

二、检测通道(侦察与枚举)

2.1 对象级侦察

参数分析:

  • 分页/游标:page[offset]page[limit]cursornextPageToken——常泄露或接受跨租户/跨状态。
  • 目录/列表端点作种子:search/list/suggest/export 常泄露对象 ID,供二级利用。
  • arjun -u <url>(GET)或 arjun -u <url> -m POST 找未文档化参数,常翻出 ?include_deleted=1?as_user=…?owner_id=… 这类扩大 IDOR 面的隐藏过滤条件。

枚举技巧:

  • 类型切换:{"id":123} vs {"id":"123"}、数组 vs 标量、对象 vs 标量。
  • 边界值:null/空/0/-1/MAX_INT、科学计数法、溢出。
  • 重复键/参数污染:id=1&id=2、JSON 重复键 {"id":1,"id":2}(解析器优先级)。
  • 大小写/别名:userId vs userid vs USER_ID;resourceId/targetId/account 等别名。
  • 虚拟文件系统下的路径穿越:/files/user_123/../../user_456/report.csv

UUID/不透明 ID 来源:日志、导出、JS bundle、分析端点、邮件、公开动态;基于时间的 ID(UUIDv1、ULID)在窗口内可能可猜。

2.2 功能级侦察

  • 面枚举:管理员/员工控制台与 API、支持工具、经网关暴露的「仅内部」端点;隐藏按钮与禁用的 UI 路径(特性开关)映射到仍然存活的端点;GraphQL schema 里的 mutation 与仅管理员字段/类型;gRPC service descriptor(reflection);移动客户端 bundle/网络日志常泄露额外端点/角色。
  • 信号:UI 上 401/403,但直接 API 调用返回 200;不同传输状态码不一致;直接调用被拒但经后台 job 成功;只改头部(role/org)就改变访问,token 不变。

2.3 字段级侦察

  • 面映射:带自动绑定的控制器(request.json → model);镜像模型的 GraphQL input 类型;经 API 暴露的管理员/员工工具;OpenAPI/GraphQL schema 揭示隐藏字段或枚举;客户端 bundle 与移动 app 里检查表单与 mutation payload 找字段名。
  • 形态变体:数组 vs 标量、嵌套 JSON、意外键下的对象;点号/括号路径 profile.role/profile[role]/settings[roles][];重复键与优先级 {"role":"user","role":"admin"};稀疏/patch 格式(JSON Patch/JSON Merge Patch,尝试加入禁止路径)。

三、利用方法与技术

3.1 对象级利用

横向与纵向访问:用同一 token 在不同主体间交换对象 ID 探横向;用低权限 token 重复探纵向;针对部分更新(PATCH、JSON Patch/JSON Merge Patch)做静默的非授权修改。

批量与批处理:批量端点(批量更新/删除)常只校验第一个元素;在数组中段插入跨租户 ID;引用外部对象 ID 的 CSV/JSON 导入可绕过创建时检查。

二级 IDOR:用 list/search 端点、通知、邮件、webhook、客户端日志收集合法 ID;直接获取或修改这些对象;操纵分页/游标跳过过滤,拉取他人页面。

Job/Task 对象:从一个用户拿 job/task ID 去取另一个用户的结果(export/{jobId}/downloadreports/{taskId});引用他人 task ID 取消/审批其任务。

文件/对象存储:直接对象路径或弱作用域签名 URL;尝试 key 前缀变更、content-disposition 技巧、跨租户复用陈旧签名;用其他租户的 share token 替换;尝试大小写/URL 编码变体。

GraphQL:

query IDOR { me { id } u1: user(id: "VXNlcjo0NTY=") { email billing { last4 } } u2: node(id: "VXNlcjo0NTc=") { ... on User { email } } }

滥用 batching/aliases 单请求取多个用户节点;Relay 全局 node 模式下解码 base64 ID 并交换原始 ID;经特权类型上的 fragment 过度取数据。

微服务与网关:token 混淆——为服务 A 签发的 token 因共享 JWT 验证但缺 audience/claim 校验,被服务 B 接受;头部信任——反向代理/API 网关注入/信任 X-User-IdX-Organization-Id,尝试覆写或删除;上下文丢失——异步消费者(队列、worker)重处理请求时不再复查授权。

多租户:经 header、子域、路径参数探测租户作用域(X-Tenant-ID、org slug);混合「token 的 org」与「另一 org 的资源」;测跨租户报表/分析汇总与管理视图。

WebSocket:每订阅授权——channel/topic 名不可被猜中(user_{id}org_{id});subscribe/publish 校验必须服务端执行,不能只在握手;订阅自己 channel 后尝试带目标用户 ID 发消息。

gRPC:直接的 protobuf 字段(owner_idtenant_id)常绕过 HTTP 层中间件;用不同主体的 token 经 grpcurl 验证引用。

集成:引用外部对象的 webhook/回调(如 invoice_id)未校验所有权即处理;第三方导入器因缺租户绑定把数据同步进错误租户。

3.2 功能级利用

动词漂移与别名:替代方法(GET 执行状态变更;POST vs PUT vs PATCH 差异;X-HTTP-Method-Override/_method);执行同一动作但校验更弱的替代端点(legacy vs v2、移动 vs Web)。

边缘 vs 核心不匹配:边缘拦截但核心服务 RPC 直接接受;经暴露的 API 路由或 SSRF 调内部服务;网关注入的身份 header 覆盖 token claim——提供冲突 header 测优先级

特性开关绕过:客户端检查的特性门槛,直接调后端端点;仅管理员 mutation 在 UI 隐藏但仍存活,经 GraphQL 或 gRPC 工具调用。

mutation Promote($id:ID!){ a: updateUser(id:$id, role: ADMIN){ id role } }

批处理 job 路径:创建导出/导入 job 允许,但 finalize/approve 缺授权——finalize 他人的 job;重放执行特权动作但不校验调用方的 webhook/后台任务端点。

content-type 路径:JSON vs form vs multipart 用不同中间件——用最宽松的解析器发动作。

GraphQL/gRPC/WebSocket:resolver 级每 mutation/字段校验,别假设顶层 auth 覆盖嵌套 mutation 或管理员字段;滥用 aliases/batching 夹带特权字段,持久化查询有时绕过 auth 转换;gRPC 经反射列出 service/method,调用被网关隐藏的管理员方法;WebSocket 握手级 auth,确保特权事件(如 admin:impersonate)逐消息授权。

3.3 字段级利用

提权:注册/资料更新时设置 role/isAdmin/permissions;切换暴露的 admin/staff 标志。

所有权接管:改 ownerId/accountId/tenantId 占有资源;跨用户/租户移动对象。

特性门槛绕过:经 flags/features 字段启用 premium/beta/特性开关;抬高 seatCount/限额/配额。

计费与权益:改 plan/price/prorate/trialEndcreditBalance;绕过服务端重算。

嵌套与关系写入:可写的嵌套 serializer 或 ORM 关系,允许在调用方作用域之外创建/关联对象。

GraphQL 专项:input 类型缺字段级授权——在 mutation input 尝试禁止字段;配合 aliasing/batching 对比效果;mutation 后立即用 fragment 过度取变更字段。

ORM 框架边界:Rails(accepts_nested_attributes_for 的深嵌套、strong parameters 配置错误);Laravel($fillable/$guarded 误用,guarded=[] 全开);Django REST Framework(可写嵌套 serializer、read_only/extra_kwargs 缺口、partial update);Mongoose/Prisma(schema path 未过滤、select:false 不挡写入、upsert 默认值)。

解析器与校验器缺口:校验器在绑定后运行且不覆盖额外字段;未知字段在响应里被静默丢弃但底层已持久化;移动/Web/网关之间白名单不一致——替代编码绕过校验流水线。

四、绕过技巧

三类越权共享一套绕过思路,核心是「不同传输/编码/网关之间授权不一致」。

解析器与传输:

  • content-type 切换:application/jsonapplication/x-www-form-urlencodedmultipart/form-data
  • 方法隧道:X-HTTP-Method-Override_method=PATCH;或在错误接受状态变更的端点上用 GET。
  • JSON 重复键/数组注入绕过朴素校验器。

参数污染:查询/body 里重复参数影响服务端优先级(id=123&id=456),两种顺序都试;混合大小写/别名参数名让网关与后端不一致(userId vs userid)。

缓存与网关:CDN/代理 key 混淆——响应 key 不含 Authorization 或租户 header,把缓存对象暴露给其他用户;操纵 VaryAccept header;重定向链与 304/206 行为可跨租户泄露内容。

头部信任(BFLA/Mass Assignment):提供 X-User-Id/X-Role/X-Organization header;移除或与 token claim 冲突;观察哪个来源胜出。

路由影子(BFLA):跳过新中间件链的 legacy/替代路由(/admin/v1 vs /v2/admin)。

幂等与重试(BFLA):重试/重放 finalize/approve 端点——应用状态却不每次校验执行者。

竞态窗口(对象级):time-of-check vs time-of-use——在并行请求中,于校验与执行之间改变引用 ID(详见第 06 节竞争条件)。

盲通道(对象级):用差异响应(状态、大小、ETag、时延)探测存在性;owned vs foreign 对象的错误形态常不同;HEAD/OPTIONS、条件请求(If-None-Match/If-Modified-Since)可在不取完整内容的情况下确认存在。

Mass Assignment 专属:

  • content-type 切换:JSON ↔ form ↔ multipart ↔ text/plain,某些代码路径只校验一种。
  • key path 变体:点号/括号/对象重塑,经不同 binder 触达嵌套字段。
  • 批量路径:bulk 操作跳过逐项检查;在大批量里插入单个恶意对象。
  • 竞态与重排:并发两个更新——第一个设禁止字段,第二个规范化;最终状态可能保留禁止变更。

五、验证与误报排除

确认一个越权真实存在的稳妥步骤:

  1. 演示非授权访问/动作/字段写入:对象级——访问不属于调用方的对象(内容或元数据);功能级——低权限主体成功调用受限动作(同样输入,正确角色成功、另一低角色失败);字段级——一个最小请求加入敏感字段,非特权调用方的持久化状态发生改变。
  2. 正确实现下失败:证明同样的请求在授权正确实现时会失败。
  3. 跨通道一致:至少两种传输证明同一非授权访问(如 REST 与 GraphQL),或两种编码。
  4. 持久状态证据:前后快照、审计日志、权威来源(账本、管理视图);对嵌套/批量,证明禁止字段在子对象或数组元素中被写入。
  5. 可复现:给出可复现步骤与证据(owner vs non-owner 的请求/响应)。

常见误报:

  • 对象级:设计上公开/匿名的资源;内容本就公开的「软私有」数据;不泄露敏感内容的幂等元数据查询;所有通道上正确的行级校验;对他人资源返回空数组/null(静默拦截而非暴露——与 owner 视图对比确认数据确实缺失,而非仅被响应形态隐藏)。
  • 功能级:被误标为管理员但公开文档化的只读端点;有明确策略、对所有角色开放的预览/beta 特性开关;模拟环境里 admin 端点被 stub、无副作用。
  • 字段级:服务端重算派生字段(plan/price/role)忽略客户端输入;字段标 read_only 且跨编码一致强制;仅 UI 端变化、无持久化效果。

六、影响评估

  • 跨账户数据泄露:PII/PHI/PCI;跨租户违反合同与监管边界。
  • 非授权状态变更:转账、角色变更、取消;经 Mass Assignment 提权到管理员/员工功能。
  • 跨租户/跨账户资源接管:经所有权字段或 tenant header 移动对象。
  • 金融/计费操纵与配额滥用:退款/发信用、套餐/价格覆写、限额抬升。
  • 策略/审批绕过:切换验证或状态标志,绕过审批工作流。
  • 监管/审计违规:绕过审批工作流导致的合规与审计问题(GDPR/HIPAA/PCI)、欺诈、声誉损害。

⚠️ 越权是 OWASP API Top 1(BOLA)与 Web Top 的常客。即便「只读」的对象级泄露,在合规与隐私层面也是高危;能改密码/邮箱/角色的越权等同于账户/系统接管。

本节要点回顾

  1. 三类越权同根:对象级(IDOR/BOLA,换 ID)、功能级(BFLA,换动作)、字段级(Mass Assignment,加字段)——本质都是「主体×对象×动作×字段未在服务边界绑定」。
  2. 核心心法:授权必须在执行动作的服务边界绑定主体/动作/对象/字段;UUID 不透明不代表安全——拿到就测;UI 门槛、网关、先前步骤都不能替代服务自身检查。
  3. 对象级面:横向/纵向/跨租户/跨服务;引用位置(路径/查询/body/header/cookie/JWT/GraphQL/gRPC);展开/投影开关常在 resolver 绕过授权。
  4. 功能级面:垂直授权、特性门槛(边缘 vs 核心)、传输漂移、网关信任、后台 worker 不复查;高价值动作=角色/支付/审批/数据删除/2FA。
  5. 字段级面:敏感字段族(role/isAdmin/ownerId/plan/限额/特性开关/计费);形态变体(数组/嵌套/点号/重复键/patch);ORM 边界(Rails/Laravel/DRF/Mongoose)。
  6. 侦察工具:arjun 找隐藏参数;列表/导出端点作 ID 种子;类型/边界值/重复键/大小写别名/二级 IDOR;GraphQL aliases/batching、gRPC reflection。
  7. 绕过本质:不同传输/编码/网关之间授权不一致——content-type 切换、方法隧道、参数污染、头部信任、路由影子、缓存 key 混淆、竞态窗口、盲通道差异。
  8. 验证五步:演示非授权访问/动作/字段写入、正确实现下失败、跨通道一致、持久状态证据、可复现;警惕公开设计资源、stub 端点、服务端重算等真实误报。
  9. 影响与链式:数据泄露、提权、跨租户接管、计费操纵、审批绕过;IDOR+CSRF/IDOR+Stored XSS/IDOR+SSRF/IDOR+Race 放大影响。

下一节,我们看 SSRF——当服务器替用户去取远程内容,这条「隧道」就直通内网与云控制面。


发布者: 作者: 灏天文库 转发
评论区 (0)
U