api-commons/spectral-owasp-ruleset

GitHub: api-commons/spectral-owasp-ruleset

基于 Spectral 的 OWASP API Security Top 10 规则集,为 OpenAPI 文档提供一行代码集成的静态安全检查与治理层。

Stars: 0 | Forks: 0

# Spectral OWASP API 安全规则集 **一个精心策划、自主拥有且有据可查的 [Stoplight Spectral](https://github.com/stoplightio/spectral) 规则集,专为 [OWASP API Security Top 10 (2023)](https://owasp.org/API-Security/editions/2023/en/0x11-t10/) 设计。** `@api-common/spectral-owasp-ruleset` 让任何团队都能**通过一行代码**为其 OpenAPI lint 添加一层真正的**安全 治理层**。它将 22 项 OWASP 检查映射到全部十个 OWASP API 安全类别,仅使用 Spectral 的 **内置函数** —— 无需自定义 JavaScript —— 因此它可以在 Spectral 运行的任何地方运行。 **Swagger 2.0 和 OpenAPI 3.x,功能对等。** Spectral 会自动检测文档的 格式,每项检查都会针对其适用的结构运行。与格式无关的检查 (schema 边界、清单元数据、全局安全性、TRACE、外部文档)不带 `formats` 标签,并在两种格式上都会触发。在两种规范在结构上存在差异的地方 — 安全方案(`components.securitySchemes` 对比 `securityDefinitions`)、 传输方式(`servers` 对比 `host`/`schemes`),以及请求/响应正文 (`content` 媒体类型映射对比 body 参数 + 响应 `schema`) —— 3.x 规则被标记为 `formats: [oas3]`,而一个 `-oas2` 孪生规则为 Swagger 2.0 提供相同的 OWASP 基础。这些检查在任何格式下都不会产生误报或空操作。 为什么会有这个项目:一项针对 1,005 个公共 API pipeline 的研究发现,只有 **14%** 的 pipeline 运行了任何形式的安全 规则,而只有 **3.4%** 的 pipeline 为其安全工具输出了 SARIF。 该规则集通过一套可采用的、**有据可查的** 规则集弥补了这一差距 —— 每条规则都指明了它所防御的 OWASP 项,解释了相关风险,并链接到了 来源。 这是 [API Commons 工具](https://apicommons.org/tools/) 之一,与 [Spectral Reporter](https://reporter.apicommons.org)、 [API Validator](https://validator.apicommons.org)、 [API Discovery](https://discover.apicommons.org)、 [API Documentation](https://documentation.apicommons.org)、 [API Reusability](https://reusability.apicommons.org) 和 [MCP Install](https://install.apicommons.org) 并列。 ## 有据可查、自主拥有的规则 每条规则都带有其出处,展示了治理规则 *应该* 是什么样的: - 一个稳定的、映射到 OWASP 的 **id**(例如 `owasp-api1-bola-operation-security-defined`) - 一段关于它所解决的风险的 **description** - 一条在每次发现问题时显示的 **message** - 一个 **severity**(`error` / `warn` / `info`) - 一个 **documentationUrl**,直接链接到特定的 OWASP API Security Top 10 项目 ## 一行代码采用 **远程扩展 (Remote extends)** —— 通过 URL 引用规则集,无需安装(指向你固定的标签/提交上的 原始文件): ``` # .spectral.yaml extends: - "https://raw.githubusercontent.com/api-commons/spectral-owasp-ruleset/main/owasp-api-top10.yaml" ``` **或者从 npm 安装** 并通过包名进行扩展: ``` npm i -D @api-common/spectral-owasp-ruleset ``` ``` # .spectral.yaml extends: - "@api-common/spectral-owasp-ruleset" ``` 你可以将其叠加在 Spectral OpenAPI 核心规则之上: ``` extends: - "spectral:oas" - "@api-common/spectral-owasp-ruleset" ``` 然后运行 lint: ``` npx @stoplight/spectral-cli lint openapi.yaml ``` ## 它检查什么 —— 规则 → OWASP 项 → 严重性 OWASP API Security Top 10 部分涉及到静态 OpenAPI 文档无法完全表达的 **runtime** 授权和 滥用决策。如果一个项是可以直接进行 lint 的,我们就会提供一个真正的检查;如果不能,我们会提供我们所能做到的最强有力的 **静态代理**(例如,“此操作上是否 *声明了* 身份验证?”),并将剩余部分标记为 **advisory**。我们不会伪造覆盖率。 **Formats** 列显示了每项检查的适用范围:**both** = 一项 与格式无关的规则;**3.x + 2.0 twin** = 一项 `formats: [oas3]` 规则加上 一个检查等效 Swagger 2.0 结构的 `-oas2` 孪生规则(名称如下)。 | 规则 id | OWASP 项 | 检查内容 | 严重性 | 覆盖率 | 格式 | | --- | --- | --- | --- | --- | --- | | `owasp-api1-bola-operation-security-defined` | API1 BOLA | 每个操作都声明了 `security` 要求(对象级 authz 需要经过身份验证的请求) | warn | proxy | both | | `owasp-api2-auth-security-schemes-defined` | API2 Broken Auth | `components.securitySchemes` 定义了 ≥1 种方案 | error | lintable | 3.x + `…-oas2` twin (`securityDefinitions`) | | `owasp-api2-auth-apikey-not-in-url` | API2 Broken Auth | API-key 方案使用 `in: header`/`cookie`,从不使用 `query`/`path` | error | lintable | 3.x + `…-oas2` twin (2.0: 仅 `in: header`) | | `owasp-api2-auth-no-http-basic` | API2 Broken Auth | 没有 HTTP Basic 认证方案 | warn | lintable | 3.x + `…-oas2` twin (2.0: `type: basic`) | | `owasp-api2-auth-oauth2-https-urls` | API2 Broken Auth | OAuth2 授权/token/刷新 URL 均为 `https://` | error | lintable | 3.x + `…-oas2` twin (2.0: 方案上的 url,无 `flows`) | | `owasp-api3-bopla-response-schema-defined` | API3 BOPLA | 每个响应 `content` 都声明了 `schema`(可审查暴露的属性) | warn | proxy | 3.x + `…-oas2` twin (2.0: `responses[2xx].schema`) | | `owasp-api3-bopla-request-schema-defined` | API3 BOPLA | 每个请求 `content` 都声明了 `schema`(限制批量赋值) | warn | proxy | 3.x + `…-oas2` twin (2.0: `in: body` 参数 `schema`) | | `owasp-api4-resource-array-maxitems` | API4 Resource Consumption | 数组 schema 声明了 `maxItems` | warn | lintable | both | | `owasp-api4-resource-string-maxlength` | API4 Resource Consumption | 字符串 schema 声明了 `maxLength` | info | lintable | both | | `owasp-api4-resource-integer-bounds` | API4 Resource Consumption | 整数/数字 schema 声明了 `maximum` | info | lintable | both | | `owasp-api5-bfla-global-security-defined` | API5 BFLA | 声明了顶层的 `security` 基线 (default-deny) | warn | proxy | both | | `owasp-api6-sensitive-flows-rate-limit-response` | API6 Sensitive Business Flows | 改变状态的操作记录了 `429` 响应 (throttling) | info | proxy | both | | `owasp-api7-ssrf-url-property-format` | API7 SSRF | 承载 URL 的属性声明了 `format: uri` 以供审查 | info | proxy | both | | `owasp-api8-misconfig-https-servers` | API8 Security Misconfiguration | 所有 `servers` URL 均为 `https://` | error | lintable | 3.x + `…-oas2` twin (2.0: `schemes` https/not http) | | `owasp-api8-misconfig-no-trace-method` | API8 Security Misconfiguration | 没有 `trace` HTTP 方法 (阻止 XST) | error | lintable | both (TRACE 仅适用于 3.x,在 2.0 上为空操作) | | `owasp-api8-misconfig-servers-defined` | API8 Security Misconfiguration | 声明了 `servers` | warn | lintable | 3.x + `owasp-api8-misconfig-host-defined-oas2` (2.0: `host`) | | `owasp-api9-inventory-info-version` | API9 Inventory | 存在 `info.version` | error | lintable | both | | `owasp-api9-inventory-contact-defined` | API9 Inventory | 存在 `info.contact` (已知的所有者) | warn | lintable | both | | `owasp-api9-inventory-operation-description` | API9 Inventory | 每个操作都有 `description` (无影子 endpoint) | warn | lintable | both | | `owasp-api9-inventory-operationid-defined` | API9 Inventory | 每个操作都有 `operationId` | warn | lintable | both | | `owasp-api9-inventory-servers-not-example` | API9 Inventory | Server URL 不是占位符 (`example.com`/`localhost`) | warn | lintable | 3.x + `owasp-api9-inventory-host-not-example-oas2` (2.0: `host`) | | `owasp-api10-consumption-externaldocs-https` | API10 Unsafe Consumption | `externalDocs.url` 为 `https://` | info | proxy | both | **22 项 OWASP 检查,覆盖了全部 10 个 OWASP API Security Top 10 (2023) 类别 —— 适用于 Swagger 2.0 和 OpenAPI 3.x。** 13 项检查是单一且与格式无关的 规则;9 项是 `formats: [oas3]` 规则加上一个 `-oas2` 孪生规则(在 `owasp-api-top10.yaml` 中共有 31 条规则条目)。 ### 按 OWASP 项划分的可 lint 与 advisory | OWASP 项 | 静态覆盖率 | | --- | --- | | **API1 BOLA** | **Proxy** —— 对象级 authz 属于 runtime;我们要求每个操作都 *声明* 身份验证。 | | **API2 Broken Authentication** | **Lintable** —— 方案存在性、API-key 位置、无 Basic、HTTPS OAuth URL。 | | **API3 BOPLA** | **Proxy** —— 属性级 authz 属于 runtime;我们要求提供请求/响应 schema,以便审查暴露/可写的属性。 | | **API4 Unrestricted Resource Consumption** | **Lintable** —— payload 上的 `maxItems`/`maxLength`/`maximum` 边界。 | | **API5 BFLA** | **Proxy** —— 功能级 authz 属于 runtime;我们要求一个 default-deny 的 `security` 基线。 | | **API6 Sensitive Business Flows** | **Proxy / advisory** —— “敏感”属于业务上下文;我们推动在改变状态的操作上返回 `429`。在网关处确认实际的节流。 | | **API7 SSRF** | **Proxy / advisory** —— 服务器是否获取用户 URL 在规范中是不可见的;我们将承载 URL 的输入标记为 `format` + 允许列表审查。真正的防御依赖于 runtime 主机允许列表。 | | **API8 Security Misconfiguration** | **Lintable** —— HTTPS 服务器、无 TRACE、声明了服务器。 | | **API9 Improper Inventory Management** | **Lintable** —— 版本、联系人、每个操作的描述/operationId、无占位符主机。 | | **API10 Unsafe Consumption of APIs** | **Proxy / advisory** —— 上游消耗在规范中是不可见的;我们要求文档指向他人的 URL 必须是 HTTPS。在 runtime 验证第三方响应。 | **advisory** 的剩余部分 —— 对象/属性/功能级授权 决策 (API1/API3/API5)、敏感流程滥用 (API6)、SSRF 允许列表 (API7),以及第三方响应验证 (API10) —— 均属于 runtime 关注点。 请在代码、测试和你的网关中强制执行它们;该规则集确保 文档至少 *暴露* 它们以供审查。 ## 在 GitHub Actions 中使用(专用安全作业 + 可选 SARIF) 将 OWASP 规则集作为其独立的门禁运行,与你常规的风格 lint 分开,这样 一旦出现安全回归就会非常明确 —— 并且(可选)上传 SARIF,以便发现的问题 显示在仓库的 **Security → Code scanning** 标签页中。 ``` name: API Security Governance on: [push, pull_request] jobs: owasp-api-security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Fail the build on any OWASP error-severity finding. - name: OWASP API Security lint run: | npx @stoplight/spectral-cli lint openapi.yaml \ -r https://raw.githubusercontent.com/api-commons/spectral-owasp-ruleset/main/owasp-api-top10.yaml # Optional: emit SARIF for GitHub code scanning (does not fail the job). - name: OWASP API Security lint (SARIF) if: always() run: | npx @stoplight/spectral-cli lint openapi.yaml \ -r https://raw.githubusercontent.com/api-commons/spectral-owasp-ruleset/main/owasp-api-top10.yaml \ -f sarif -o results.sarif || true - name: Upload SARIF if: always() uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif category: owasp-api-security ``` 将原始 URL 固定到标签或提交 SHA(而不是 `main`)以实现可重现的 CI,或者 安装 npm 包并从已提交的 `.spectral.yaml` 中 `extends: ["@api-common/spectral-owasp-ruleset"]`。 ## 在本地试用 该仓库提供了四个测试夹具(一对 3.x 和一对 Swagger 2.0)以及一个 证明该规则集在两种格式上都会实际触发的测试: ``` npm install # installs the Spectral CLI (devDependency) npm test # lints both format pairs: insecure fires all 10 # families, clean is silent, and no rule throws # 或者手动 lint fixtures: npm run lint:insecure # 3.x: 30 findings across 20 rules, all 10 families npm run lint:clean # 3.x: 0 findings npm run lint:insecure:oas2 # 2.0: 30 findings across 19 rules, all 10 families npm run lint:clean:oas2 # 2.0: 0 findings ``` `fixtures/insecure.yaml` (API 3.x) 和 `fixtures/insecure-oas2.yaml` (Swagger 2.0) 是故意写坏的安全规范(查询字符串中的 API key、无操作 `security`、明文传输、HTTP Basic、缺少 body/响应 schema、缺少清单元数据)。`fixtures/clean.yaml` 和 `fixtures/clean-oas2.yaml` 是可以通过检查的、管理良好的规范。 ## 规则是如何编写的 每条规则仅使用 Spectral 的默认函数 —— `defined`、`truthy`、`falsy`、`pattern`、`schema`、`enumeration`、`casing`、 `length`、`alphabetical` —— 因此除了 Spectral 本身之外,没有什么需要安装、审计或信任的。请阅读 `owasp-api-top10.yaml`;它包含大量注释, 按 OWASP 项分组,并解释了每项检查和每个 advisory 缺口背后的原因。 ## 待办事项(给接手此任务的人) - [ ] **创建并推送 GitHub 仓库** `api-commons/spectral-owasp-ruleset` (此树已在本地提交,但 目前 **没有远程仓库** —— 尚未进行任何推送)。一旦推送,上面原始的 `extends` URL 就会生效。 - [ ] **npm publish** `@api-common/spectral-owasp-ruleset`(作用域 `@api-common` 是单数形式)。`publishConfig.access` 已经设为 `public`;在 仓库建立后运行一次 `npm publish` 即可。 - [ ] 考虑标记一个发布版本,以便 CI `extends` URL 可以固定一个 SHA/标签 而不是 `main`。 - [ ] 可选择在 `apicommons.org/tools/` 下发布一个着陆页,并将其添加 到工具索引中。 ## 许可证 [Apache-2.0](./LICENSE) —— 免费且开源。版权所有 2026 API Commons (Kin Lane)。 这是 [API Evangelist](https://apievangelist.com) 的一个项目,由 [API Commons](https://apicommons.org) 维护。当你需要帮助 建立 API 安全治理时,API Evangelist 提供专业的 [治理服务](https://apievangelist.com/services/)。
标签:API安全, JSON输出, OpenAPI, Spectral, 安全合规, 暗色界面, 网络代理, 自定义脚本, 静态扫描