关于 security-testing
security-testing 是一项面向工程师的安全测试技能,帮助将 OWASP 检查和负向测试纳入持续集成。它组合 DAST、依赖与供应链扫描、SAST、密钥扫描及自定义认证测试,覆盖应用和 LLM 相关风险。
主要功能
- 01OWASP Top 10 安全测试清单
- 02分层 DAST、SCA 与 SAST 扫描
- 03认证与访问控制负向测试
- 04依赖、SBOM 与构建来源检查
- 05LLM 应用安全测试要点
适用场景
- 01在每次 PR 中运行安全检查
- 02验证用户无法访问他人数据
- 03检查依赖与构建供应链风险
- 04测试 LLM 输出和工具权限风险
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill security-testing安装后在 Claude Code 中输入/security-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/auth-tests.mdowasp-tests.mdscanning-and-ci.md详细介绍
发现问题
先检查 .agents/qa-project-context.md;如果文件存在,就使用其中的信息,并跳过已回答的问题(身份验证机制、合规要求、基础设施)。然后:
- 威胁模型: 团队是否已识别关键资产、威胁行为者和攻击面?如果没有,在编写测试前进行轻量级威胁建模——这能帮助确定哪些类别最重要。
- 身份验证机制: 会话 Cookie、JWT、OAuth 2.0/OIDC、API 密钥还是 MFA?每种机制都有各自的负面路径测试(算法混淆、会话固定、状态篡改)。
- 合规要求: SOC 2、HIPAA、PCI DSS、GDPR?这些标准要求特定控制措施——使用
compliance-testing对其进行映射;此技能只验证这些控制措施的行为。 - 现有安全工具: 是否已在运行 OSV-Scanner、Snyk、Dependabot、Semgrep 或 ZAP?添加重复项前,先检查 CI 配置中已有的安全阶段。
- API 表面: REST、GraphQL 还是 gRPC?每种协议都有特定的注入和授权攻击向量。
- 部署模式: 云端(AWS/GCP/Azure)、容器还是无服务器?云元数据端点是 SSRF 的主要目标,错误配置则属于 A02。
核心原则
-
安全是持续过程,而非一个阶段。 每个 PR 都在 CI 中运行扫描,而不是每季度进行一次渗透测试。在引入漏洞的 PR 中发现问题只需几分钟;同一漏洞若在生产环境中才被发现,就会演变成安全事件。
-
OWASP Top 10 是底线,而非上限。 它涵盖影响最广泛的常见类别。特定领域的威胁(医疗数据、金融交易、多租户隔离)还需要额外分析。
-
纵深防御——没有任何单一工具能捕获所有问题。 ZAP 会漏掉身份验证逻辑漏洞,SCA 会漏掉自定义代码问题,Semgrep 会漏掉运行时问题。将 DAST、SCA、SAST、身份验证测试和密钥扫描分层组合。一个层的盲点若由另一个层覆盖,回归就必须绕过所有层才能漏过。SCA 值得单独设为一层,因为已发布代码的大部分来自第三方——依赖项中的已知 CVE 是攻击者最省力的攻击向量,因此每次构建都应进行扫描。
-
尽早发现。 在每类问题的最早阶段进行检测:提交时运行 SAST 和密钥扫描,PR 中运行依赖项与供应链检查,在预发布环境中运行 DAST,每次测试运行都执行自定义身份验证测试。参见
shift-left-testing,了解此流程所依托的开发与 QA 工作流。 -
测试攻击者,而非用户。 成功路径身份验证只能证明登录有效。安全测试要验证退出登录会使会话失效、过期令牌会被拒绝、角色提升会失败,以及格式错误的载荷会被安全拒绝。负面路径才是测试本身。
OWASP Top 10(2025)测试清单
2025 年列表(最终版,owasp.org/Top10/2025/)重新排列了类别,并新增了两个类别。相较于 2021 年的变更:
- A03 Software Supply Chain Failures 为新增类别(取代“易受攻击和过时的组件”;范围扩展至来源、构建流水线信任和 SBOM)。
- A10 Mishandling of Exceptional Conditions 为新增类别。SSRF 不再单独列项——其测试现在归入 A01(访问控制)和 A06(不安全设计)。
- A02 Security Misconfiguration 从 A05 前移。
- A07 Authentication Failures——名称缩短(删去“Identification and”)。
- A09 Security Logging and Alerting Failures——更名(原为“Logging and Monitoring”)。
各类别的可运行测试代码请参见 references/owasp-tests.md。
A01:访问控制失效
排名第 1 的漏洞。用户执行了超出预期权限的操作。如果攻击者诱使服务器访问内部资源,SSRF 现在也属于访问控制失效。
测试内容: IDOR(更改资源 ID 以访问其他用户的数据)、缺失功能级访问控制(普通用户访问管理端点)、路径遍历(../../etc/passwd)、CORS 配置错误、SSRF(用户提供的 URL 访问内部网络、云元数据端点、file://)。
A02:安全配置错误
默认凭据、不必要的功能、详细错误信息。从 A05 上调而来——仍然是最容易利用的入口。
测试内容: 在生产环境中禁用堆栈跟踪、更改默认凭据、禁用不必要的 HTTP 方法(如 TRACE)、关闭目录列表、管理面板不对外公开、云存储桶不对外公开。
A03:软件供应链失效
2025 年新增。不只是“依赖项过时”,还包括来源证明、构建流水线完整性,以及端到端的软件供应链。
测试内容: 提交锁文件,且 CI 从锁文件安装依赖项(npm ci,绝不使用 npm install);生成 SBOM 并将其存储为构建产物(Syft / anchore/sbom-action);为构建产物提供来源证明(SLSA v1.0 L2/3,通过 cosign / actions/attest-build-provenance 签名);每个 PR 都进行依赖项审查;CI 密钥不暴露给 fork;将自托管运行器与不可信的 PR 代码隔离。
请参阅 references/owasp-tests.md,了解依赖项审查 / SBOM / 来源证明工作流以及锁文件漂移检查。
A04:加密失效
敏感数据因加密薄弱或缺失而暴露。
测试内容: TLS 版本 / 密码套件 / HSTS;密码使用 bcrypt/argon2 哈希(而非 MD5/SHA1);URL、日志或错误信息中不包含敏感数据;Cookie 带有 Secure、HttpOnly、SameSite;存在安全标头(HSTS、X-Content-Type-Options: nosniff、X-Frame-Options)。
A05:注入
将不可信数据发送给解释器。
测试内容: 参数 / 字段 / 标头中的 SQL 注入;用户内容中的 XSS(反射型、存储型、DOM 型);更改状态的操作是否存在 CSRF;文件名、搜索查询、Webhook URL 中的命令注入。
A06:不安全设计
单靠实现无法修复存在缺陷的架构。包括设计层面的 SSRF(接受 URL 的功能未使用允许列表)、未设置速率限制的凭据填充攻击、业务逻辑滥用。
测试内容: 身份验证端点的速率限制(并发发起 15 次登录尝试,预期响应中出现 429);业务逻辑滥用(负数量、优惠券叠加);失败尝试后锁定账户;任何会获取用户提供 URL 的功能都采用允许列表架构。
A07:身份验证失效
身份验证机制失效、密码薄弱、凭据填充攻击。登录后轮换会话、拒绝过期的 / alg:none JWT、RBAC 矩阵、OAuth 状态篡改。请参阅 references/auth-tests.md。
A08:软件或数据完整性失效
更新未签名、不安全的反序列化、不可信的 CI/CD。
测试内容: CDN 脚本是否使用子资源完整性(SRI);存在内容安全策略(Content-Security-Policy)标头,且不包含 'unsafe-inline' / 'unsafe-eval'。
A09:安全日志记录和告警失效
日志记录不足,且对已记录的事件缺少告警。2025 年更名,旨在强调没有告警的日志只能作为事后证据,不能用于检测。
测试内容: 记录失败的登录,并在超过阈值时触发告警;记录管理操作审计日志,并对非工作时间发生的事件触发告警;日志中不包含密钥 / 个人身份信息;监控告警流水线本身。
A10:异常情况处理不当
2025 年新增。错误和意外状态都是攻击面——默认放行、未捕获的异常泄露内部信息、错误路径中的竞态条件,以及“出了问题”时跳过安全检查。
**测试内容:**错误响应不泄露堆栈跟踪/框架名称/数据库架构;身份验证失败时默认拒绝;超时和部分故障绝不能绕过授权;所有错误路径都进行资源清理;对每个端点进行模糊测试,并验证响应始终符合文档中规定的错误约定。
OWASP LLM Top 10(2025)
如果你的应用内嵌了大模型(聊天机器人、RAG、Agent、Copilot),上面的经典 Top 10 并未涵盖其故障模式——请使用 OWASP Gen AI Security Project 的独立列表(genai.owasp.org/llm-top-10/)。这是面向安全/CI 门禁的视角:每个类别列出一行“测试内容”。如需深入覆盖 LLM01 和 LLM02 的行为——通过工具/RAG 数据进行间接注入、保护测试者的技巧、越狱红队测试,以及可运行的注入检测器——请转交给 ai-system-testing;此处不要重复相关内容。
| ID | 类别 | 测试内容 |
|---|---|---|
| LLM01 | 提示词注入 | 直接和间接注入(隐藏在检索文档、工具输出、文件内容中的指令)覆盖系统意图。→ ai-system-testing 中有深入覆盖。 |
| LLM02 | 敏感信息泄露 | 模型通过精心构造的提示词泄露个人身份信息、机密、其他租户的数据或训练数据。→ ai-system-testing 中有深入覆盖(检测器、范围限定的测试)。 |
| LLM03 | 供应链 | 模型、适配器、数据集和插件的来源;固定/已验证的权重;遭投毒的第三方模型或 LoRA。 |
| LLM04 | 数据与模型投毒 | 训练/微调/RAG 摄取数据的完整性;通过受污染来源注入后门和偏见。 |
| LLM05 | 输出处理不当 | 大模型输出未经净化便传递给下游解释器——由生成文本引发 XSS、SSRF、SQLi、命令注入。 |
| LLM06 | 权限过度 | Agent 拥有超出任务所需的工具/权限/自主权;可在无人类把关的情况下删除、付款或发送电子邮件。 |
| LLM07 | 系统提示词泄露 | 系统提示词可被提取;更糟的是,依赖它来保存机密或实施本应由服务端负责的授权。 |
| LLM08 | 向量与嵌入弱点 | RAG 检索跨越租户/权限边界;嵌入反演;受污染的向量作为上下文返回。 |
| LLM09 | 错误信息 | 将自信捏造的内容(幻觉事实、虚假引文/URL、不安全代码)当作权威信息接受。 |
| LLM10 | 无限制消耗 | 没有令牌/速率/成本上限——由提示词驱动的资源耗尽、拒付攻击,以及通过查询量提取模型。 |
LLM05(输出处理不当)是经典 Top 10 衔接回来的地方:将大模型输出视为不可信输入,并对其生成的任何内容重新执行 A05 注入检查。
自动化安全扫描
完整的流水线会分层执行 DAST、依赖项/供应链扫描、SAST 和密钥扫描。配置和 CI 工作流见 references/scanning-and-ci.md。
- OWASP ZAP(DAST): 每次 PR 都针对预发布环境进行基线扫描;API 使用
zap-api-scan.py。当前版本为 ZAP 2.17.0(每周发布w2026-MM-DDDocker 标签)。**ZAP MCP Server(2026 年 4 月)**可让编码 Agent 驱动爬取/主动扫描/警报分析,支持“扫描差异”工作流。 - **依赖项/供应链:**OSV-Scanner 是默认的门禁工具——支持多种语言,发现任何漏洞都会以非零状态码退出。添加 SBOM(Syft)和来源证明(
cosign/attest-build-provenance),以满足 A03 要求。npm audit --audit-level=high是一种噪声较多、仅基于 semver 的快速检查,不应作为门禁工具(它不会标记非严格 semver 版本,而且不能可靠地以非零状态码退出)。 - SAST:****Semgrep
p/owasp-top-ten是 SAST 门禁工具。eslint-plugin-security是较弱的辅助信号——见下方说明;将它作为 lint 阶段的提醒,而非覆盖手段。 - **密钥扫描:**在 CI 中使用带
--only-verified的 TruffleHog;在提交前使用git-secrets。
避免依赖 eslint-plugin-security 作为 SAST 门禁工具——截至 2026 年年中,它仅提供约 13 条规则,自 2020 年以来规则数量没有实质性增长,基准测试显示它对可检测漏洞的漏报率接近 90%。其 4.0.0 版本兼容 flat config,因此配置可以运行,但应将其作为 Semgrep 的补充,绝不能用它替代 Semgrep。
ESLint 10(2026 年 2 月)彻底移除了 .eslintrc——只有 flat config(eslint.config.js)可用。任何 .eslintrc.* 安全配置在 ESLint 10 中都已失效;仅在固定使用 ESLint 8 的代码库中使用。两个配置块见 references/scanning-and-ci.md。
身份验证测试模式
测试会话管理、JWT(过期、alg: none 混淆、错误密钥签名)和 RBAC 矩阵。完整代码见 references/auth-tests.md。还要测试登录后的会话轮换(会话固定)和 OAuth 状态参数篡改。
CI 集成
完整的安全流水线包含五个层次,每个层次对应一个 CI 步骤:
- 密钥扫描——使用带
--only-verified的 TruffleHog - 依赖项检查——OSV-Scanner(发现任何漏洞都会失败);为 A03 添加 SBOM 和来源证明
- SAST——使用 Semgrep
p/owasp-top-ten作为门禁;ESLint 安全插件作为较弱的辅助工具 - DAST——针对预发布 URL 进行 ZAP 基线扫描
- 自定义身份验证测试——
npx playwright test --project=security
**将安全作为 PR 门禁:**OSV-Scanner 发现任何漏洞都会以非零状态码退出,并直接阻止合并。如果改用 npm audit 作为门禁,则解析 npm audit --json,并在高危/严重漏洞数量 > 0 时执行 exit 1——npm audit 本身不能可靠地以非零状态码退出。可运行的门禁配置见 references/scanning-and-ci.md。
反模式
只在发布前进行安全测试。 越晚发现问题,修复成本越高。每个 PR 都要扫描,而不是每季度扫描一次。
依赖单一工具。 ZAP 会漏掉身份验证逻辑漏洞;SCA 会漏掉自定义代码问题;ESLint 会漏掉运行时问题。应分层使用多种工具。
把几乎废弃的代码检查工具当作 SAST 覆盖。 单独使用 eslint-plugin-security 几乎什么都检测不到(约 13 条规则,检测能力停留在 2020 年左右)。应以 Semgrep p/owasp-top-ten 作为门禁;保留代码检查工具作为提醒。
忽略依赖警告。 “以后再修”会变成已知 CVE 的积压。通过 OSV-Scanner 对高危/严重漏洞使构建失败。
只测试正常路径下的身份验证。 登录正常——很好。注销会使会话失效吗?过期令牌还能访问资源吗?角色提升是否可行?
在测试文件中硬编码密钥。 存有真实密钥的测试本身就是漏洞。使用环境变量和 CI 密钥。
跳过 SSRF 测试。 任何接受 URL 的功能(webhook、图片上传、导入)都是 SSRF 攻击途径。测试内部地址和云元数据端点。
只断言单一状态码,而实际有多个有效状态码。 SSRF/CSRF/异常情况测试有一组可接受的状态码。使用 expect([400, 403, 422]).toContain(response.status())——toBeOneOf 不是内置匹配器,会在运行时抛出异常。
只测试已知载荷。 参考资料中的 XSS/SQLi 载荷只是示例,并不全面。使用 ZAP 维护的载荷数据库以扩大覆盖范围。
验证
证明断言确实会触发——如果安全测试套件只是空跑(URL 错误,匹配器从未执行),那还不如没有测试。
- 将一项负向路径测试指向一个故意存在漏洞的目标,并确认测试失败。在本地运行 OWASP Juice Shop 等已知存在漏洞的应用:
IDOR/注入/缺少安全头部的测试应报告失败。如果针对 Juice Shop 的所有测试都通过,说明断言没有触及应用——在信任针对自有预发布环境的绿色结果之前,先修正选择器/URL。docker run --rm -p 3000:3000 bkimminich/juice-shop BASE_URL=http://localhost:3000 npx playwright test --project=security - 确认匹配器形式能够运行。
grep -r "toBeOneOf" tests/必须没有任何返回结果——每个可接受值集合的断言都使用expect([...]).toContain(...)。 - 确认门禁会因植入漏洞而失败。 添加一个已知存在漏洞的依赖,运行 OSV-Scanner 步骤,并确认任务以非零状态退出。之后将其移除。
完成标准
- 已提交的
owasp-coverage.md(或用于断言此项的 CI 任务)将每个 OWASP 2025 类别映射到至少一项带标签的测试,或映射到一条有理由说明的“已缓解/已接受风险”记录——不得有任何类别被悄然遗漏。 - OSV-Scanner(或同等工具)在 CI 中运行,且对高危/严重漏洞,任务以非零状态退出——通过“验证”中的植入漏洞检查确认。
- Semgrep
p/owasp-top-ten在 CI 中运行,且主分支上没有未解决的问题(ESLint 安全插件可以作为次要的非门禁信号运行)。 - ZAP 基线扫描针对预发布环境运行,并在每次运行时将报告作为 CI 工件上传(
if: always())。 - 安全 Playwright 项目(
--project=security)针对预发布环境运行时退出状态为 0,且指向 OWASP Juice Shop 时会产生失败(证明断言确实会触发)。 - 身份验证/会话边界情况均有通过的测试:拒绝 CSRF、拒绝过期令牌、拒绝
alg:none、注销时使会话失效、防止 RBAC 角色提升。 - 测试文件中没有真实密钥(
grep/TruffleHog 检查通过)。
相关技能
- ci-cd-integration — 流水线阶段接线和部署门控机制;了解如何运行这些步骤,请看这里;了解这些步骤验证什么,请看本技能。
- compliance-testing — 将安全控制映射到法规(SOC 2、HIPAA、PCI、GDPR);本技能验证控制是否有效,该技能验证控制是否选对。
- ai-system-testing — 产品自身的大模型功能。负责深入开展 OWASP LLM Top 10 工作:间接提示词注入、注入检测器、敏感信息泄露测试、越狱红队测试。本技能列出用于 CI 门控的大模型类别;该技能负责保护 Agent。
- api-testing — 不涉及攻击者模型的 REST/GraphQL 功能性身份验证、输入和速率限制测试;没有模拟威胁时,请看本技能。
- shift-left-testing — 开发与 QA 工作流、TDD,以及本技能所遵循的左移原则的完成定义。
- test-environments — 安全的测试环境配置、密钥管理、网络隔离。
- database-testing — 数据库层面的数据完整性和访问控制。
参考文件(在 references/ 中)
- owasp-tests.md — OWASP A01–A10(IDOR、SSRF、注入、加密、安全标头、速率限制、供应链 SBOM/来源证明、异常情况)的可运行 Playwright 代码,以及可接受状态集匹配器说明。
- scanning-and-ci.md — ZAP、OSV-Scanner/Snyk、Semgrep + ESLint flat-config SAST、密钥扫描,以及包含可运行依赖门控的五层 CI 流水线。
- auth-tests.md — A07 的会话、JWT(
alg:none、过期)和 RBAC 矩阵测试。