设想一个假设的场景。一家B2B开票平台通过REST API为自家的Web应用、移动应用以及合作伙伴的会计系统提供服务。某合作伙伴的集成正确完成了认证:身份提供方签发令牌,API网关校验其签名、受众和有效期,请求都以「已认证」的状态记入日志。由于集成自身代码中的缺陷,它请求了另一家客户的发票,而API把这张发票返回了。令牌是真实的,调用方就是它声称的身份,网关也尽到了职责。问题出在别处:在服务层,没有人问过这个调用方是否有权查看这一个具体对象。
同一个假设平台还暴露出另外两个缺口。客户方用户提交的更新请求中多带了一个把发票标记为「已审批」的字段,而服务把收到的所有字段都写入了数据库。夜间导出任务从一个共享缓存中生成各租户的CSV文件,而这个缓存的键只包含报表类型。所有请求都通过了认证,但关于能读取什么、修改什么、触发什么的决策都出了错,而且每次错在不同的地方。
这正是一次有价值的REST API安全评估的核心思想。认证回答「谁在调用」,授权回答「这个调用方此刻在这个租户中,能对这个对象、属性和功能做什么」。一个有效的令牌或一块全绿的网关监控面板,都无法回答第二个问题。下文说明如何围绕这一区别界定范围,如何安全地测试身份、授权、租户隔离和业务流程,如何要求可用的证据,以及如何做出采购决策。
REST API安全评估涵盖什么
REST API安全评估是一项经过授权的结构化检查,关注API如何识别调用方、允许每个调用方做什么、如何校验接收的数据,以及如何保护返回的数据。仅做网站扫描并不足够,因为访问决策围绕资源、方法、令牌、属性和机器对机器的客户端做出。评估也不是认证证书、鉴证或保证意见,而是在某一时间点对约定范围进行的技术检查,并为测试了什么、发现了什么提供证据。
清单:API、版本、环境与机器客户端
评估从清单开始,因为未经测试的区域可能造成不存在漏洞的错觉。清单包括已文档化和未文档化的端点、所有仍在运行的API版本(包括为旧客户端保留的老版本),以及所有存放真实或近似真实数据的环境:生产环境、预发布环境、沙箱和合作伙伴测试租户。健康检查、调试、管理和内部端点即使「不打算公开」也应列入清单,因为决定暴露程度的是可达性,而不是意图。
机器客户端,即合作伙伴集成、移动应用、定时任务、Webhook、内部服务以及持有长期凭据的服务账户,需要单独登记:各自如何认证、持有哪些权限范围或角色、可以代表哪些租户执行操作。隐性信任往往在服务间流量中不断累积;关于微服务渗透测试与基于证据的范围界定的文章对这一层有深入讨论。
范围说明与书面授权
一份站得住脚的范围说明应在测试开始前由双方确认,并至少写明以下内容:
- API清单:纳入范围的端点、版本和环境,以及测试中发现未文档化端点时的处理方式
- 身份模型:认证方式、令牌类型、会话处理、角色、租户和机器客户端
- 数据分类:哪些资源包含个人、财务或运营数据
- 排除项与约束:排除的第三方服务、生产环境限制、请求速率上限、测试时间窗口以及有权叫停测试的人员
- 授权记录:由谁批准测试、有效期多长、针对哪些目标
最重要的是,范围必须有获授权人员签发的书面授权作为依据。本文任何内容都不意味着允许测试您不拥有或未获授权评估的系统。
身份、会话与令牌的信任边界
REST API运行在HTTP之上。MDN将HTTP描述为应用层的客户端-服务器协议,既用于机器对机器通信,也用于以编程方式访问API。MDN称HTTP为无状态协议:协议本身不会把请求彼此关联起来。这一点常被误读。服务器端会话依然可以存在,请求也不必携带调用方的完整身份:连续性建立在协议之上,而每个请求都携带某种服务器可据以识别调用方的东西。
Cookie、令牌与会话标识符
常见的方式有两种。第一种是服务器保存会话状态,并向客户端发放标识符,通常放在Cookie中;MDN解释说,Cookie通过Set-Cookie和Cookie请求头增加状态。标识符本身不包含权限,它只是一个引用,服务器在每次请求时据此找到所保存的状态。第二种是客户端出示令牌,通常放在Authorization请求头中:不透明令牌需要由服务器或身份提供方查询,而自包含令牌携带经过签名的声明,例如主体、受众、权限范围和有效期,由API在本地校验。
两种模式的失效方式不同。会话标识符必须不可预测、有效期合理,并在注销和权限变更时失效。对自包含令牌而言,关键在于签名、可接受的算法和签发方、受众、有效期、吊销,以及声明到权限的映射;CISA的Secure by Design资料专门讨论了如何保护令牌和断言免遭伪造、窃取和滥用。在两种模式下,凭据最多只能证明谁在调用,却不能决定调用方可以触及哪个对象、哪个属性或哪个功能。
信任决策发生在哪里
要发现授权缺口,可以把系统中所有做出信任判断的位置标在图上,并确认每个位置实际检查了什么。下表只是起点,真实的图需要根据目标系统的架构绘制。
左右滑动查看对照
| 边界 | 能够决定什么 | 通常无法决定什么 | 评估要问的问题 |
|---|---|---|---|
| 身份提供方 | 主体是谁、哪个客户端在调用、签发了哪些权限范围 | 某个对象是否属于该主体所在的租户 | 权限范围、受众和有效期是否足够窄? |
| API网关 | 令牌是否有效、路由访问、请求速率上限 | 单条记录和单个属性的归属 | 是否有服务依赖网关已经检查过对象访问? |
| 服务处理程序 | 对象归属、可写属性、该角色允许的功能 | 脱离原始请求、稍后运行的任务的行为 | 是否对路由的每个方法和每个版本执行授权? |
| 异步任务与导出 | 任务读取、汇总和交付什么数据 | 在没有显式租户上下文时调用方的意图 | 租户上下文是否端到端传递? |
| 缓存与间接引用 | 针对某个键或引用返回哪份结果 | 请求方是否有权获得该结果 | 缓存键和下载引用是否包含租户与权限信息? |
对象级、属性级与功能级授权
OWASP API Security Top 10 2023把授权问题分为三个独立类别:对象级授权失效、对象属性级授权失效和功能级授权失效。该清单是一份安全意识文档,不应把条目顺序理解为某个具体环境中各类问题出现频率的排名。它对评估的价值在于提供了词汇:这是三个不同的问题,每个都需要各自的测试。
对象级授权
对象级授权要回答的是:调用方能否操作这一条具体记录;这正是开头场景中的缺口。测试人员每种角色至少需要两个账户,在多租户系统中还需要在至少两个租户中各有账户。他们确认每个身份能看到自己的对象,并在访问他人对象时被拒绝,而且覆盖资源的每一种方法以及提供该资源的每个API版本。间接路径需要同样的检查:父对象、搜索过滤条件、报表引用或导出链接。
属性级授权与批量赋值
属性级授权要回答的是:调用方能否读取或写入某个具体字段。在输出方向,如果直接序列化整个对象而不是经过过滤的视图,响应就会暴露内部标志、其他用户的联系方式或面向其他角色的价格。在输入方向,当服务把请求体中的所有字段都绑定到数据模型时,就会出现批量赋值(mass assignment)问题,调用方可以设置界面从未提供的状态、角色、所有者或审批属性。评估针对每种角色检查返回了哪些属性,以及提交的属性中哪些被接受、哪些被忽略、哪些被拒绝。持久的修复方式是按角色和操作明确列出属性允许清单,而不是维护一份危险字段的黑名单。
功能级授权
功能级授权要回答的是:调用方究竟能否调用某项操作。管理操作和批量操作、审批、代他人操作、配置变更和客服支持工具,常常与普通功能位于同一个API中,仅靠路径或方法区分。评估根据文档和流量建立「角色—功能」矩阵,检查每种角色在其权限列之外都会被拒绝,包括未文档化的方法和缺少后来新增权限检查的旧版API。
同步与异步路径中的租户隔离
在多租户SaaS中,租户隔离是采购方最关心的问题,但它的测试范围往往过窄。读取端点拒绝访问其他租户的记录是必要的,但并不充分:数据还会通过绕开可见读取端点的路径跨越租户边界。
租户隔离评估至少应覆盖以下路径:
- 导出与报表:文件、定时报表和下载链接限定在发起请求的租户范围内,对其他租户无效
- 后台任务与队列:工作项显式携带租户上下文,处理程序执行这一上下文,而不是信任消息中的标识符
- 缓存:针对单个租户或用户的数据,其缓存键包含租户上下文,必要时还包含权限上下文,确保绝不返回其他租户的结果
- 间接引用:搜索索引、存储路径、Webhook、通知模板和内嵌标识符,都接受与直接读取相同的归属检查
- 管理与客服路径:跨租户工具相互隔离、记录日志,只开放给确实需要的角色
异步路径更难测试,因为结果出现得更晚、出现在别处。因此,范围中应约定如何安全地触发和观察任务,例如在预置了数据的测试租户中进行。关于多租户范围界定的更全面讨论,请参阅SaaS企业渗透测试指南。
业务流程与资源消耗
OWASP API Security Top 10 2023把资源消耗不受限制和对敏感业务流程的访问不受限制列为两个独立类别。两者相关但并不相同,评估应分别对待。
资源消耗是一个请求或一连串请求的成本:CPU、内存、存储、付费第三方调用、外发消息和代价高昂的查询。检查内容包括分页、请求体和文件大小、批量大小、查询复杂度、超时,以及针对每个客户端、租户和凭据的请求速率上限。敏感业务流程是指合法功能以业务从未预期的规模或顺序被使用:批量注册、反复兑换折扣和推荐奖励、自动抢购限量商品、跳过审批步骤。每个请求都可能合乎授权,却仍然是有害流程的一部分。
安全测试需要事先约定:以最少的请求证明限制薄弱,不耗尽资源,并向产品负责人确认什么算滥用。如何界定这类工作的范围,可参阅关于业务逻辑安全测试服务的文章。
端点清单之外的HTTP攻击面
MDN的参考文档说明,请求方法表示请求的目的;GET和POST最常用。对评估人员而言,重要的是资源实际接受哪些方法,而不是文档列出了哪些方法,以及授权是否在所有方法上一致执行。一个典型缺口是:某资源对读取做了保护,却接受一个未文档化、可修改数据的方法;只有系统地测试各种方法才能发现。
MDN将状态码分为五类,API如何使用它们能揭示很多信息:响应不一致会暴露资源是否存在,服务器错误会泄露实现细节。MDN还说明了基于MIME类型的Content-Type以及通过Accept进行的内容协商,因此值得检查API对意外内容类型和格式的反应。
CORS规定浏览器允许哪些源读取API响应。它对浏览器客户端很重要,但不能替代服务器端授权,也不能限制任意非浏览器客户端。根据MDN,条件请求有助于在多个客户端同时写入时防止更新丢失,因此关系到数据完整性。升级到WebSocket的协议切换和经由代理的流量,都应明确写入或排除在范围之外。简明检查清单如下:
- 每个资源的方法覆盖,包括未文档化的方法
- 每个端点的身份认证要求,包括健康检查、调试接口和旧版本;公开访问的例外必须经过明确设计,并限制其暴露的数据和操作
- 供浏览器调用的端点的CORS策略
- 令牌、会话标识符与Cookie的处理、有效期和吊销
- 与安全相关的事件是否以防御人员真正可用的方式记录
方法与衡量基准
规划、执行与执行后阶段的流程纪律
NIST SP 800-115《信息安全测试与评估技术指南》于2008年9月发布,取代了2003年的SP 800-42。其目的是帮助组织规划和实施技术安全测试与检查、分析发现,并制定缓解策略。对API评估项目而言,这意味着流程纪律:规划工作和交战规则,在约定范围内执行测试,执行结束后分析结果,把结果转化为缓解措施并进行复测。
该指南描述的是各种手段及其优势与局限,而不是一套完整的测试计划。因此,评估应组合多种手段,并说明每种手段的局限;由于该文件早于大多数API工具,具体检查应取自针对应用的测试指南。
ASVS、WSTG、OWASP Top 10清单与CWE
这些检查来自OWASP Web安全测试指南(WSTG),其中认证、授权、会话管理和输入校验等领域可直接用于REST。请注明所用的WSTG版本,因为OWASP指出,版本化内容反映的是某一时间点的状态。
OWASP应用安全验证标准(ASVS)为测试技术安全控制提供依据,同时提供安全开发要求清单,用以统一验证工作的覆盖范围和严格程度。对采购方而言,它把一句含糊的「测试API」承诺转化为双方认可、可逐条验证的要求清单。要求编号可能随版本变化,因此OWASP建议使用带版本的引用格式,例如v5.0.0-1.2.5,并把不带版本的编号视为指向最新内容。要求清单以CSV、JSON等格式发布,因此可以方便地按每条要求、每个API记录通过、未通过或不适用。
面向Web应用的OWASP Top 10和OWASP API Security Top 10都是安全意识文档:适合用来解释优先事项,却不能替代测试计划,只核对十个条目必然留下缺口。MITRE的CWE(包括CWE Top 25最危险软件弱点)提供描述根本原因的词汇;CISA的Secure by Design警报旨在消除整类漏洞;NIST网络安全框架2.0则设定了风险管理的目标成果,评估结果应在这一背景下解读。关于如何结合使用这些依据,可参阅从范围到决策的应用安全审计方法一文。
安全的测试数据与生产环境约束
测试条件本身带有真实风险:授权测试会接触到属于他人的数据。生产环境更贴近实际,但测试可能影响可用性和客户。预发布环境通常可以降低对客户的风险。其发现能在多大程度上适用于生产环境,取决于网关规则、身份提供方设置、功能开关和任务调度等方面的差异;必须记录这些差异及结论的适用范围。
无论选择哪种环境,交战规则都应规定:
- 为每种角色准备测试账户,并准备使用合成数据的测试租户,确保跨租户检查永远不需要读取真实客户的记录
- 非破坏性限制:允许哪些写入、删除和批量操作,以及针对哪些对象
- 请求速率上限和时间窗口,资源与业务流程测试尤其需要
- 意外看到真实数据时的处理方式:尽量少查看,只复制证据所需的内容,并及时通知
- 紧急停止机制:双方联系人以及暂停测试的条件
另一项权衡是向测试人员提供多少信息。黑盒测试接近外部攻击,但大量时间花在信息发现上;提供规范、每种角色的账户,并在可能时提供源代码,可以提高每个工作日的覆盖范围。自动化对已知模式覆盖广、可重复,但授权和逻辑缺陷要求理解谁可以做什么,这意味着需要测试人员使用多个角色亲自验证。无论哪种方式,结果都只是某一时间点的快照,报告应明确说明。
证据、复测与验收
NIST把分析发现和制定缓解策略视为测试本身的一部分。每个发现都应包含:可复现的证据;受影响的端点、方法和版本;所使用的角色和租户;适用时附带版本的ASVS要求编号;CWE分类;结合暴露程度和数据敏感度的风险评级;修复建议;以及复测结果。证据应让工程师能够用测试账户复现相应行为,并经过脱敏处理,不含敏感数据。
下面的矩阵展示了采购方如何在项目开始前定义验收标准,让「已修复」对所有人都意味着同一件事。
左右滑动查看对照
| 领域 | 报告中的最低证据要求 | 修复的验收标准 | 复测要求 |
|---|---|---|---|
| 对象级授权 | 来自两个身份的请求,显示可访问对方的对象 | 在服务器端对资源的每个方法和每个版本执行归属检查 | 在相同及新建的对象和相关间接引用上重复验证 |
| 属性级授权与批量赋值 | 显示暴露属性的响应,或显示被禁止属性被接受的请求 | 按角色和操作明确列出可读、可写属性的允许清单 | 检查原有属性以及该模型的其他敏感属性 |
| 功能级授权 | 包含被拒绝和成功调用的「角色—功能」矩阵 | 低权限角色在任何路径、方法和版本上调用特权功能均被拒绝 | 针对受影响的功能组重新运行矩阵 |
| 异步路径中的租户隔离 | 从触发到任务输出的追踪记录,其中含有另一个测试租户的数据 | 租户上下文在任务、导出、缓存和引用中得到执行 | 为两个租户重新触发,并检查输出和链接 |
| 资源限制与业务流程 | 以最少操作证明某项限制缺失或薄弱 | 与产品负责人约定的客户端、租户和流程限制 | 在约定阈值处确认限制生效,且不耗尽资源 |
更大的回报来自根本原因。根据MITRE的说法,了解常见根本原因能为开发和架构规划提供反馈,有助于消除整类缺陷。应把反复出现的发现转化为共享授权库、网关策略、序列化默认配置和回归测试,在新增认证流程、租户或API版本后重新评估,并跟踪修复时间和复发率。关于漏洞修复管控及如何证明修复有效的文章介绍了这一闭环。
采购决策:界定范围并选择API评估服务商
方法和衡量基准明确后,选择服务商就容易多了。CISA的Secure by Demand指南面向采购谈判,澳大利亚信号局下属的澳大利亚网络安全中心(ASD ACSC)与CISA联合发布的关于选择安全技术的指南强调可验证性。这里的原则相同:要求服务商展示他们如何工作,而不只是口头描述。
- 清单与授权列出API、版本、环境和机器客户端,然后取得书面批准,明确交战规则和停止条件。
- 信任边界标明身份、令牌、会话和租户上下文在哪里被检查,以及哪些服务依赖别处的检查。
- 授权矩阵针对不同角色和租户规划对象级、属性级和功能级测试,并覆盖导出、任务、缓存和间接引用。
- 安全执行在合成租户中按约定限制进行测试,把自动化的广度与人工授权测试结合起来。
- 证据与复测依据证据矩阵验收发现,通过复测确认修复,并用回归测试固化反复出现的原因。
向服务商提出的问题
- 覆盖范围由哪个WSTG版本和哪些ASVS要求界定?规划、执行和报告如何进行?
- 测试对象级、属性级和功能级授权需要多少账户、角色和租户?
- 如何在导出、后台任务、缓存和间接引用中测试租户隔离,而不只是读取操作?
- 能否提供脱敏的报告样本、复测政策以及生产环境工作规则,包括意外接触真实数据和紧急停止?
警示信号
- 把原始扫描结果包装成渗透测试
- 把某份OWASP Top 10清单作为唯一检查清单
- 引用标准却不注明版本号
- 完全不讨论跨多个角色和租户的授权测试
- 把评估说成认证、鉴证或安全保证
- 不愿在测试前落实书面授权和范围
对于关于资质认证、客户和成果的说法,都应独立核实。面向互联网、涉及敏感数据和多租户设计的API,值得进行更深入的人工授权测试,并选择更广泛的ASVS要求;处理低敏感度数据的内部API,可以先做自动化测试,再对认证和授权进行有针对性的人工审查。在工作开始前把测试深度形成书面记录,以便在不同版本和不同服务商之间比较结果。为此,可以通过Pentest.red准备渗透测试范围,事先约定系统、访问权限、限制条件和预期证据。
API评估之后应当得到什么
REST API安全评估只有在经过授权、事先规划、以证据为依据,并且不把一次成功的登录误当作访问正确时,才真正有用。NIST SP 800-115提供流程纪律,WSTG提供测试用例,ASVS提供带版本的要求,OWASP API Security Top 10 2023为对象级、属性级和功能级授权、资源消耗以及业务流程提供词汇,CWE提供描述根本原因的语言。把它们与清单、信任边界图、覆盖任务、导出和缓存的租户隔离测试以及复测闭环结合起来,就能说明已测试API版本的检查深度、已确认问题和复测结果。后续变更需要继续观察,并在适当时重新评估。
PENTEST.RED
讨论渗透测试范围与报价
首先明确系统、访问权限、限制条件和预期证据。
本文以深入研究为基础,经过编辑整理,注重清晰表达和实际应用。