API 权限校验别只看登录态:从 BOLA 到字段级越权的防护清单

枫少@KillBoy
枫少@KillBoy
枫少@KillBoy
管理员
222
文章
0
粉丝
Web安全10111字数 1950阅读6分30秒阅读模式
摘要API 安全里最容易被忽视的不是“有没有登录”,而是用户是否有权访问某个对象、某个字段和某个业务动作。本文结合 OWASP API Security Top 10,整理 BOLA ...
AI智能摘要
大多数团队做API权限校验,只盯着“接口是否需要登录”。但OWASP API Security Top 10里,BOLA和字段级越权排名前两位,恰恰说明“已登录≠已授权”。真正的漏洞往往藏在对象ID、字段和业务流程里。这篇文章不是讲理论,而是给出一份实战防护清单:从顺序ID暴露到响应字段白名单,6个落地检查点。如果你还在用登录态判断一切,建议上线前先对照自查——你大概率漏掉了至少3个越权洞。
— AI 生成的文章内容摘要

很多 Web 系统在做 API 安全检查时,会先确认“接口是否需要登录”。这一步当然重要,但它只解决了身份识别问题,并不等于授权安全。真正容易出问题的地方,往往是接口已经知道“你是谁”,却没有继续判断“你能不能访问这个对象、这个字段、这个业务动作”。
在 OWASP API Security Top 10 2023 中,Broken Object Level Authorization(BOLA,对象级授权缺失)被列为 API1;Broken Object Property Level Authorization(字段/属性级授权缺失)被列为 API3。它们共同指向一个现实问题:现代系统越来越依赖前后端分离、移动端、开放平台和内部微服务,API 暴露的对象 ID、字段和业务流程越多,越权风险就越容易被放大。
API 权限校验别只看登录态:从 BOLA 到字段级越权的防护清单

一、为什么“已登录”不等于“已授权”

一个常见误区是:只要接口校验了 Token、Session 或 JWT,就认为请求是安全的。但登录态只能说明请求来自某个已认证用户,并不能说明这个用户有权访问请求中的资源。
例如,一个订单详情接口可能形如:

GET /api/orders/10086

如果服务端只是确认用户已登录,却没有确认订单 10086 是否属于当前用户,攻击者就可能通过修改 ID 枚举其他订单。OWASP 对 BOLA 的描述也强调:只要 API 端点接收用户可控的对象 ID,并据此访问数据源,就应在每个相关函数中执行对象级授权校验。

二、BOLA:对象级越权的几个高频场景

  • 顺序 ID 暴露:订单、工单、简历、发票等对象使用自增 ID,攻击者很容易尝试相邻编号。
  • 只在前端隐藏入口:前端按钮不可见,但后端接口仍然可以直接调用。
  • 多租户隔离不足:后台系统只按用户角色判断权限,却忘了判断租户、组织、项目空间。
  • 服务端信任客户端传参:接口直接使用请求里的 user_idcompany_idproject_id,没有和当前会话绑定校验。
  • 内部接口外露:原本给管理端或内部服务使用的接口,被移动端、前端或网关间接暴露。

这类问题的修复重点不是“把 ID 换成 UUID 就安全了”。UUID 可以降低枚举成功率,但不能替代授权判断。真正可靠的做法是:每次访问对象前,都在服务端根据当前用户、角色、租户、资源归属和操作类型做明确校验。

三、字段级越权:比对象越权更隐蔽

字段级越权常常出现在两个方向:一是接口返回了用户不该看到的敏感字段;二是接口允许用户修改自己不该修改的字段。OWASP API3:2023 将过去常说的“过度数据暴露”和“批量赋值”合并到字段/属性级授权问题中,本质上都是没有对对象属性做细粒度控制。
典型风险包括:

  • 用户资料接口返回手机号、身份证号、内部备注、风控标签等敏感字段;
  • 普通用户更新个人资料时,可以提交 role=adminbalanceis_verified 等不应开放的字段;
  • 后台列表接口为了“开发方便”直接返回完整对象,前端只是不展示敏感字段;
  • GraphQL 或通用查询接口没有限制字段选择范围,导致敏感属性可被探测。

字段级越权的危险之处在于,它不一定表现为明显的 403 绕过。有些接口返回 200,看似业务正常,但响应体里已经包含了不该暴露的数据。

四、落地防护清单

1. 把授权检查放在服务端核心路径

不要依赖前端隐藏按钮、网关路径限制或客户端传参。每个涉及对象读取、修改、删除、导出、审批的 API,都应在服务端检查当前主体是否有权执行该动作。

2. 建立资源归属模型

至少要明确:资源属于哪个用户、哪个租户、哪个组织、哪个项目;当前用户在这个范围内是什么角色;本次操作是读取、修改、删除还是管理。没有资源归属模型,越权检查很容易散落在业务代码里,长期维护成本会越来越高。

3. 响应字段采用白名单

对外 API 不建议直接返回数据库实体或 ORM Model。更稳妥的方式是使用 DTO、Serializer、ViewModel 等输出层对象,只返回当前场景明确需要的字段。敏感字段默认不出现在响应里,需要时再按权限显式开放。

4. 请求字段同样采用白名单

更新接口不要把请求体直接绑定到数据库对象。应按接口场景声明允许修改的字段,例如昵称、头像、简介可以开放;角色、余额、审核状态、租户 ID 等高敏字段必须由专门的后台流程控制。

5. 多租户系统优先校验租户边界

企业后台、SaaS、工单系统、知识库、资产管理平台都容易出现跨租户访问。查询条件中不能只依赖用户提交的 tenant_id,应从当前登录态或服务端上下文获取租户范围,并在数据查询层强制带入。

6. 为敏感接口补充审计日志

对象详情、批量导出、权限变更、资金相关、账号管理等接口,应记录操作者、目标对象、来源 IP、User-Agent、操作结果和失败原因。审计日志不是替代授权的手段,但能帮助发现异常枚举和越权尝试。

五、测试时重点看什么

  • 用 A 用户登录后,替换请求中的订单 ID、项目 ID、工单 ID,确认是否能访问 B 用户资源;
  • 普通用户调用管理员接口,观察是 401、403,还是错误地返回业务数据;
  • 对更新接口添加额外字段,检查是否会被后端接收并写入;
  • 检查列表接口、导出接口、搜索接口是否能跨租户返回数据;
  • 检查接口响应是否包含内部备注、权限字段、风控字段、手机号、邮箱等不必要信息。

这里要注意:安全测试应在授权环境和明确范围内进行,避免对第三方系统做未授权探测。对自己的系统做检查时,也应优先在测试环境完成验证,再把规则固化到自动化测试和上线检查流程中。

六、工程化建议:把越权防护变成默认能力

越权漏洞之所以反复出现,很多时候不是开发人员不知道风险,而是项目缺少统一的授权框架。建议把常见能力沉淀到基础层:

  • 统一的权限中间件或策略引擎;
  • 统一的租户上下文获取方式;
  • 资源查询默认带租户和用户范围;
  • 敏感字段统一脱敏或禁止输出;
  • 接口契约中标注资源类型、动作和权限要求;
  • 把越权用例加入接口自动化测试。

安全不是把所有接口都变成复杂审批,而是在关键路径上让“默认安全”成为开发习惯。对 API 来说,登录校验只是第一步;对象级、字段级、功能级授权才是更接近真实业务风险的防线。

参考资料

 
枫少@KillBoy
  • API安全
  • BOLA
  • it2021
  • it2021.com
  • OWASP
  • web安全
  • 字段级越权
  • 安全测试
  • 访问控制
评论  10  访客  10
    • 尘埃先知
      尘埃先知 1

      说的没错,登录校验只是第一步,对象级授权才是大头

      • 嵌入式农夫
        嵌入式农夫 2

        这个清单挺实用的,字段白名单那块之前踩过坑

        • 尘外客
          尘外客 1

          还要注意那种批量导出接口,经常漏权限

          • 狼族首领
            狼族首领 0

            GraphQL的字段限制具体怎么搞?有没有现成的轮子?

            • 岁月留痕
              岁月留痕 1

              感觉有点理想化,中小项目哪有那么多资源搞统一框架

              • 机灵小松鼠
                机灵小松鼠 0

                之前接了个外包,订单ID用的uuid结果还是被搞了,后来加了校验才放心😅

                • PineconeTrail
                  PineconeTrail 0

                  又是安全文章,看得头疼但确实得重视🤔

                匿名

                发表评论

                匿名网友

                拖动滑块以完成验证