beadon/ai-security-reviewer

GitHub: beadon/ai-security-reviewer

一个由 Claude Code 驱动的双层安全审查流水线,将传统扫描工具与 AI 语义分析结合,为 npm/JS 代码库及其部署基础设施提供预部署静态安全审计。

Stars: 0 | Forks: 0

# AI 安全审查员 一个由 Claude Code 驱动的双层安全审查流水线,专为 npm/JavaScript 代码库及其部署基础设施而设计。 **第 1 层 — 自动化工具:** 专用扫描器负责处理模式匹配、已知 CVE、硬编码机密、许可证合规性、IaC 配置错误和供应链威胁。这些工具会首先运行并生成结构化结果。 **第 2 层 — AI 语义分析:** Claude 结合业务上下文对工具输出进行分诊,然后分析任何模式匹配器都无法捕获的问题:业务逻辑缺陷、授权模型错误、二阶漏洞、权限提升链和跨边界信任违规。 ## 三大技能 | 技能 | 命令 | 范围 | |-------|---------|-------| | `security-review.md` | `/security-review` | npm/JS 代码 — 注入、身份验证、业务逻辑、供应链 | | `arch-review.md` | `/arch-review` | IaC、容器、CI/CD、云配置 — Terraform、K8s、Docker、Ansible | | `full-review.md` | `/full-review` | 协调器 — 并行运行上述两项技能,并合并为一份报告 | 对于大多数 PR 审查,请使用 `/full-review`。当您只想对单层进行专注、更快速的扫描时,请使用单独的技能。 ## 前置条件 - 已安装并完成身份验证的 [Claude Code](https://claude.ai/code) - 已安装并完成身份验证的 [GitHub CLI (`gh`)](https://cli.github.com/) (`gh auth login`) 安全扫描工具(Semgrep、gitleaks、njsscan)在**本地使用时是可选的**。如果未安装,AI 分析将在没有其输出的情况下继续进行。有关在可重现环境中运行工具的信息,请参阅 [CI 工作流](#ci-workflow)。 **可选的商业工具:** [socket.dev](https://socket.dev) 提供供应链安全分析。它需要设置 `SOCKET_API_KEY` 环境变量。对公共仓库免费;私有仓库需付费计划。如果没有该密钥,技能将跳过此扫描并在报告中注明。请参阅下方的 [socket.dev 设置](#socketdev-setup)。 ## 安装 ``` git clone https://github.com/beadon/ai-security-reviewer cd ai-security-reviewer ``` 然后根据您的场景运行安装程序: ``` # 在所有项目间共享 ./install.sh --global # 安装到特定项目 (仅限 skills) ./install.sh --project /path/to/your/project # 安装 skills + CI workflow 到项目 (场景 3) ./install.sh --all /path/to/your/project ``` 安装程序会将技能文件从 `.claude/commands/` 复制到正确位置,并将 CI 工作流从 `.github/workflows/` 复制到目标仓库。协调器 (`/full-review`) 在运行时会读取其他两个技能文件——这三个文件必须安装在同一个目录中。 ## 使用方法 ### 场景 1 — 审查 Pull Request(推荐) 在本地检出 PR 分支,然后调用全面审查。这将并行运行代码级和基础设施分析。 ``` gh pr checkout ``` 然后在 Claude Code 中: ``` /full-review ``` 若要对单层进行更快、更专注的扫描: ``` /security-review # code only /arch-review # infrastructure only ``` 报告仅涵盖该 PR 引入的更改,而不是整个代码库。 **使用 socket.dev(可选):** 如果在您的环境中设置了 `SOCKET_API_KEY`,该技能将自动运行供应链扫描作为阶段 0 的一部分。要配置它: ``` export SOCKET_API_KEY=your_api_key_here ``` **使用 license-checker(无需设置):** 通过 `npx` 自动运行——无需安装。它会标记该 PR 引入的任何带有 copyleft 或未知许可证的依赖项。 ### 场景 2 — 审查完整仓库或任意分支 克隆您可以访问的任何公共或私有仓库,然后从其中运行审查。 ``` # Clone 并审查默认分支 gh repo clone / /tmp/target cd /tmp/target ``` 对于特定分支: ``` gh repo clone / /tmp/target -- --branch cd /tmp/target ``` 然后在 Claude Code 中(在 `/tmp/target` 中打开): ``` /full-review ``` 此场景特别适用于在采用依赖项或第三方仓库之前对其进行供应链和许可证审计。license-checker 和 socket.dev(如果已配置)都将扫描完整的依赖树,而 arch-review 将检查存在的任何 IaC 文件。 **注意:** 当审查完整的仓库而不是 PR 差异时,git diff 命令不会产生输出。两项技能都将使用工具扫描结果和整体代码库的语义分析继续进行。 ### 场景 3 — CI 集成审查(推荐团队使用) 在本地运行工具存在不稳定性——工具可能未安装、版本可能不同,并且结果在不同机器上无法重现。推荐的团队部署方式是将工具执行与 AI 分析分离: ``` PR opened → GitHub Actions runs all scanning tools (code + IaC) in a clean environment → socket.dev GitHub App posts its own PR comment (if installed) → All other tool results posted as a structured PR comment by the workflow → Developer runs /full-review in Claude Code → Orchestrator spawns parallel code-level + infrastructure sub-tasks → Each sub-task reads tool results from CI, adds semantic analysis → Unified report produced ``` **设置:** 1. 将 GitHub Actions 工作流添加到您的目标仓库(请参阅下方的 [CI 工作流](#ci-workflow))。 2. *(可选)* 在仓库上安装 [Socket GitHub App](https://socket.dev)。它会在每个 PR 上自动运行,并将其供应链发现作为单独的评论发布——无需工作流步骤。 3. 在审查 PR 时,将其检出并运行 `/full-review`。每个子技能将检测并使用 CI 发布的工具结果。 ## CI 工作流 工作流文件位于本仓库的 [`.github/workflows/security-scan.yml`](.github/workflows/security-scan.yml)。使用以下命令将其安装到您的目标仓库: ``` ./install.sh --ci /path/to/your/project # 或作为完整安装的一部分: ./install.sh --all /path/to/your/project ``` 它会在每次 Pull Request 时运行,在干净的环境中执行所有扫描工具,并将结果作为 `/full-review` 可以使用的 PR 评论发布。
查看工作流 YAML ``` name: Security Scan on: pull_request: branches: [main, master] jobs: scan: runs-on: ubuntu-latest permissions: pull-requests: write contents: read steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: '20' - name: npm audit run: npm audit --json > /tmp/npm-audit.json 2>/dev/null || true - name: Semgrep uses: semgrep/semgrep-action@v1 with: config: >- p/javascript p/nodejs p/secrets output: /tmp/semgrep.json output-format: json continue-on-error: true - name: gitleaks uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} continue-on-error: true - name: njsscan run: | pip install njsscan --quiet njsscan --json . > /tmp/njsscan.json 2>/dev/null || true - name: Checkov (IaC) uses: bridgecrewio/checkov-action@v12 with: output_format: json output_file_path: /tmp/checkov.json continue-on-error: true - name: hadolint (Dockerfile) uses: hadolint/hadolint-action@v3.1.0 with: dockerfile: Dockerfile format: json output-file: /tmp/hadolint.json continue-on-error: true - name: Trivy config scan uses: aquasecurity/trivy-action@master with: scan-type: config format: json output: /tmp/trivy-config.json continue-on-error: true - name: License Checker run: npx license-checker-rseidelsohn --json --excludePrivatePackages > /tmp/license-checker.json 2>/dev/null || true - name: Socket.dev CLI scan if: env.SOCKET_API_KEY != '' env: SOCKET_API_KEY: ${{ secrets.SOCKET_API_KEY }} run: | npm install -g @socketsecurity/cli --quiet socket scan create --json . > /tmp/socket.json 2>/dev/null || true - name: Post results as PR comment uses: actions/github-script@v7 with: script: | const fs = require('fs'); const read = (p) => { try { return fs.readFileSync(p, 'utf8'); } catch { return '{}'; } }; const body = [ '', '## Security Scan Results', '### npm audit', '```json', read('/tmp/npm-audit.json'), '```', '### Semgrep', '```json', read('/tmp/semgrep.json'), '```', '### njsscan', '```json', read('/tmp/njsscan.json'), '```', '### License Checker', '```json', read('/tmp/license-checker.json'), '```', '### Socket.dev', '```json', read('/tmp/socket.json'), '```', '### Checkov (IaC)', '```json', read('/tmp/checkov.json'), '```', '### hadolint', '```json', read('/tmp/hadolint.json'), '```', '### Trivy config', '```json', read('/tmp/trivy-config.json'), '```', ].join('\n'); const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, }); const existing = comments.find(c => c.body.includes('')); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body, }); } ```
## socket.dev 设置 socket.dev 是可选的,但它增加了此堆栈中其他工具无法提供的有意义的供应链覆盖范围。 **免费版(公共仓库):** 在您的仓库上安装 [Socket GitHub App](https://socket.dev)。它会在每个 PR 上自动运行,无需 API 密钥或工作流步骤。 **付费版(私有仓库):** GitHub App 对私有仓库需要付费计划。或者,在场景 1 和 2 中使用 CLI: ``` export SOCKET_API_KEY=your_api_key_here # add to ~/.zshrc or ~/.bashrc ``` 对于 CI(场景 3),在 GitHub → Settings → Secrets and variables → Actions 中将您的密钥添加为名为 `SOCKET_API_KEY` 的仓库密钥。工作流步骤仅在密钥存在时有条件地运行。 ## 工具覆盖范围 ### 代码级工具 (`/security-review`) | 工具 | 范围 | 免费? | OWASP | |------|-------|-------|-------| | `npm audit` | 依赖树中的已知 CVE | 是 (内置) | A06 | | Semgrep | 注入点、XSS、原型污染、硬编码凭据 | 是 (OSS) | A02, A03, A08 | | gitleaks | Git 历史和差异中的机密和 token | 是 (OSS) | A02 | | njsscan | Express/Node 配置错误、缺少安全中间件 | 是 (OSS) | A05, A07 | | license-checker-rseidelsohn | 依赖树中的 Copyleft 和未知许可证 | 是 (OSS) | A06 | | scancode-toolkit | 源文件头中的版权声明和许可证标识符;检测直接复制到代码库中的 GPL 污染代码 | 是 (OSS) | A06 | | socket.dev | 供应链:恶意安装脚本、域名抢注、新的/未知维护者 | 公共仓库免费;私有仓库付费 | A06 | ### 基础设施工具 (`/arch-review`) | 工具 | 范围 | 免费? | OWASP | |------|-------|-------|-------| | Checkov | Terraform、CloudFormation、K8s、Dockerfile、Ansible、Helm、Bicep | 是 (OSS) | A01, A02, A05 | | hadolint | Dockerfile 最佳实践、不安全的 ADD/RUN 模式、可变基础标签 | 是 (OSS) | A05, A08 | | Trivy (config) | K8s、Terraform、CloudFormation、Dockerfile — 与 Checkov 互补 | 是 (OSS) | A01, A05, A06 | | tflint | 特定于 Terraform provider 的规则和已弃用的资源 | 是 (OSS) | A05 | | ansible-lint | Ansible playbook 安全 — Shell 注入、权限提升滥用 | 是 (OSS) | A03, A05 | ## AI 覆盖范围(工具无法捕获这些) ### 代码级 (`/security-review`) | 类别 | 示例 | |----------|---------| | 业务逻辑缺陷 | 操作顺序混乱、一次性 token 重放、状态假设被违反 | | 授权模型正确性 | 数据获取后进行 Authz、对错误主体进行检查、跳过 authz 的分支 | | 二阶注入 | 数据被安全存储,但在不同文件中被检索并危险地使用 | | 跨文件信任边界违规 | 内部辅助函数现在从公共处理程序调用而未进行重新验证 | | 链式漏洞 | 两个低权限操作组合以提升权限 | | 具有业务影响的竞态条件 | 支付、角色更改、配额执行中的 TOCTOU | | 语义 SSRF | 用户输入通过多个文件影响出站 URL 的主机/协议 | | Token 和会话逻辑 | 缺少声明验证、token 在不同受众间重放 | ### 基础设施级 (`/arch-review`) | 类别 | 示例 | |----------|---------| | IAM 权限提升链 | 通过多跳 assume-role 从 Role A → Role B → admin | | 跨服务信任暴露 | 资源策略授予了比预期更广泛的访问权限 | | 机密处理反模式 | 任务定义中的明文环境变量、Dockerfile ARG 中的机密 | | 网络分段不匹配 | 安全组允许所有应用服务器访问 DB,而不仅仅是支付服务 | | 容器安全上下文 | 危险的能力、到 `/var/run/docker.sock` 的主机路径挂载 | | CI/CD 流水线完整性 | 可变的 action 标签、带有不受信任 checkout 的 `pull_request_target` | | 镜像来源 | 可变基础标签、Docker Hub 公共镜像、来自 URL 的 `ADD` | | 数据分类对齐 | 可能包含 PII 或凭据的资源使用了未加密的存储 | ## 输出 审查会生成一份包含两个部分的 Markdown 报告: **A 部分 — 语义发现(AI 检测):** 工具未报告的漏洞,通过对代码库的语义推理发现。 **B 部分 — 工具发现(分诊和丰富):** 自动扫描中确认的真正阳性结果,附带 AI 添加的针对特定业务的影响。 每个发现包括:严重性 (高/中/低)、OWASP 类别、置信度分数、具体的漏洞利用场景以及特定的修复建议。 ## 置信度阈值 置信度低于 **8/10** 的发现将被抑制。目标是向开发者提供零误报——漏掉一个发现的代价比警报疲劳更低。 ## 安全生命周期:此工具的定位 此流水线涵盖**预部署、静态分析**——它在任何内容发布之前对代码和配置文件运行。它回答的问题是:*这可以安全部署吗?* 它不能替代部署后扫描,后者回答的问题是:*正在运行的系统当前是安全的吗?* ``` Code written → PR opened → /full-review (this tool) → merged → deployed → post-deployment scanning ↑ ↑ Static: code + IaC files Dynamic: live systems Catches what will be introduced Catches what is currently exposed ``` ### 部署后工具(不在此流水线范围内) | 工具 | 扫描内容 | 何时运行 | |------|--------------|-------------| | **Nessus** (Tenable) | 活跃主机 — 开放端口、服务版本、操作系统补丁级别、经过身份验证的配置检查 | 部署后;安排对 staging 和生产环境的定期扫描 | | **OWASP ZAP** | 正在运行的 Web 应用程序 — HTTP 攻击面、身份验证流程、会话处理 | 针对已部署的 staging 环境;作为发布关卡的一部分 | | **Burp Suite** | 正在运行的 Web 应用程序 — 深度 HTTP/API 测试、主动扫描 | 在主要发布前手动或自动针对 staging 运行 | | **AWS Inspector / GCP Security Command Center / Azure Defender** | 云工作负载 — 正在运行的 EC2/容器/无服务器漏洞及暴露情况 | 持续;在账户级别启用 | | **Trivy** (镜像扫描模式) | 注册表中的容器镜像 — OS 包和应用程序依赖项中的 CVE | 在镜像推送到注册表时;与此工具运行的配置扫描分开 | Nessus 特别通过网络探测活跃的 IP 地址——它需要正在运行的目标和网络可达性,这使其在设计上与 PR 审查工作流不兼容。它的合适位置是对您的 staging 或生产环境进行定期扫描,或者作为部署后的发布关卡检查。 ### 版权和 IP 扫描:各归其位 | 工具 | 功能 | 适合此流水线吗? | |------|-------------|----------------------| | **scancode-toolkit** | 读取源文件头以获取版权声明和许可证标识符;检测复制到代码库中的 GPL 污染代码片段 | 是 — 在 `security-review` 阶段 0 中,范围限于更改的文件 | | **license-checker** | 读取 `package.json` 元数据以识别每个 npm 依赖项的许可证 | 是 — 已在 `security-review` 阶段 0 中 | | **FOSSA** | 结合许可证合规性、版权检测和传递性义务追踪的托管服务;对开源提供免费 | 是,适用于每次 PR (FOSSA GitHub App);完整的发布关卡扫描最好另外安排计划 | | **Black Duck** (Synopsys) | 企业级:针对庞大数据库的深度代码片段匹配、出口管制分类、完整的传递性义务追踪 | 否 — 对于每次 PR 来说太慢;适合作为完整代码库的发布关卡扫描 | 关键区别在于:`scancode-toolkit` 和 `license-checker` 可以低成本且快速地捕获*由此 PR 引入的*版权和许可证问题。Black Duck / FOSSA 的全面扫描则能全面审计*整个代码库*——适合作为发布关卡或定期的合规性审计,不适合作为快速的 PR 检查。 ## 贡献 欢迎贡献——请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 获取有关添加工具、新生态系统技能和提交 PR 的指南。 本项目基于 **GNU Affero General Public License v3.0 (AGPLv3)** 授权。请参阅 [LICENSE](LICENSE)。如果您修改此项目并将其作为网络服务公开,您必须在相同条款下发布您的源代码。
标签:AI安全审查, Chrome Headless, CI/CD安全, Claude, Claude, CSV导出, CVE检测, CVE检测, Docker安全, gitleaks, IaC安全, JavaScript安全, Kubernetes安全, Llama, LNA, MITM代理, njsscan, npm安全, PR审查, Semgrep, Terraform安全, WordPress安全扫描, 业务逻辑漏洞, 代码安全, 代码审查, 大语言模型(LLM), 安全助手, 安全左移, 开源合规, 提权链, 数据可视化, 漏洞枚举, 硬编码凭据检测, 系统提示词, 请求拦截, 越权漏洞, 静态应用安全测试(SAST)