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

枫少@KillBoy
枫少@KillBoy
枫少@KillBoy
管理员
228
文章
0
粉丝
Web安全351,556字数 1950阅读6分30秒阅读模式
摘要API 安全里最容易被忽视的不是“有没有登录”,而是用户是否有权访问某个对象、某个字段和某个业务动作。本文结合 OWASP API Security Top 10,整理 BOLA ...
AI智能摘要
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
评论  35  访客  35
    • 尘埃先知
      尘埃先知 1

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

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

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

          • 山野漫游者
            山野漫游者 1

            @ 嵌入式农夫 对啊,字段白名单最稳,直接漏过敏感字段😂

          • 尘外客
            尘外客 1

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

              • 山远人初静
                山远人初静 1

                @ 尘外客 批量导出漏权限真的很要命

                • 屁颠屁颠小短腿
                  屁颠屁颠小短腿 1

                  @ 尘外客 内部接口暴露真的很危险

                  • 尘梦
                    尘梦 1

                    @ 尘外客 导出接口权限太容易被忽略了

                  • 狼族首领
                    狼族首领 0

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

                      • 岩韵悠长
                        岩韵悠长 1

                        @ 狼族首领 graphql本身有field middleware,或者用graphql-shield之类的库能做权限控制

                      • 岁月留痕
                        岁月留痕 1

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

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

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

                            • 梦游者号
                              梦游者号 1

                              @ 机灵小松鼠 uuid只能防枚举,关键还是服务端做校验

                            • PineconeTrail
                              PineconeTrail 0

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

                              • 山间茶
                                山间茶 1

                                看不懂,但感觉好厉害的样子(⊙o⊙)

                                • 山谷回音
                                  山谷回音 1

                                  这篇讲得实在,有空细看

                                  • 尬聊高手
                                    尬聊高手 1

                                    那如果是微服务间的内部调用呢?也需要做权限校验吗?

                                    • 老鹰展翅
                                      老鹰展翅 1

                                      字段白名单管用,之前试过。

                                      • 尘埃狙击手
                                        尘埃狙击手 1

                                        uuid真能防枚举?心理安慰吧

                                        • 山行者
                                          山行者 1

                                          我之前做完token校验就以为安全了,结果被人改了订单ID看了别人的数据,后来加了归属校验才放心😅

                                            • 孤独的王者
                                              孤独的王者 0

                                              @ 山行者 uuid防枚举也就心理安慰

                                              • 山川行
                                                山川行 1

                                                @ 山行者 中小企业表示这个框架有点奢侈

                                                • 尘埃落定
                                                  尘埃落定 1

                                                  @ 山行者 租户ID最好从token里取

                                                • 沧海
                                                  沧海 0

                                                  又是长篇大论,但道理是这个道理

                                                    • 山鬼低语
                                                      山鬼低语 1

                                                      @ 沧海 确实,现在做安全太难了

                                                      • 山楂糖葫芦
                                                        山楂糖葫芦 1

                                                        @ 沧海 道理是这个道理,但改起来太麻烦

                                                        • 山雾隐
                                                          山雾隐 1

                                                          @ 沧海 又是安全文章,看得头皮发麻🤯

                                                        • 幽影迷宫
                                                          幽影迷宫 1

                                                          用户自己传tenant_id的话,服务端怎么验真假?直接取token里的不行吗?

                                                            • 泡泡小甜筒
                                                              泡泡小甜筒 0

                                                              @ 幽影迷宫 石墨烯电池真的能量产吗?感觉还早吧

                                                            • MaleficWarden
                                                              MaleficWarden 0

                                                              理想很丰满,现实中小公司哪有权限框架?

                                                                • 山羊角角
                                                                  山羊角角 1

                                                                  @ MaleficWarden 这实验条件也太苛刻了

                                                                • 玄裳
                                                                  玄裳 0

                                                                  技术文章看得头大,先收藏了

                                                                    • 海风轻语
                                                                      海风轻语 1

                                                                      @ 玄裳 期待后续测评

                                                                    • 岁月留声机
                                                                      岁月留声机 1

                                                                      技术文章太长,看着看着就跑了

                                                                      • 冷静的分析师
                                                                        冷静的分析师 1

                                                                        白名单字段这个建议实在

                                                                      匿名

                                                                      发表评论

                                                                      匿名网友

                                                                      拖动滑块以完成验证