0xkaz/devsec-scanner

GitHub: 0xkaz/devsec-scanner

一款本地优先的 DevSec 安全扫描器,通过 CLI 或桌面应用将 SAST、SCA、IaC、DAST、密钥、容器镜像及供应链扫描统一为一份报告。

Stars: 1 | Forks: 0

# DevSec Scanner 一款本地优先的安全扫描器:通过一个 CLI 或原生桌面应用运行 **SAST、SCA、IaC、DAST、secret、容器镜像及供应链**扫描,将每个工具的输出标准化为同一个 schema,并在 React 仪表板中探索结果。 所有操作均通过 Docker 在你的本地机器上运行——无需 SaaS,也不消耗 CI 分钟数。项目内置了一个参考性质的 GitHub Actions 工作流,用于演示如何在需要时将这些相同的扫描集成到流水线中。 ## 为什么开发这个工具 安全扫描往往比较费力,因此它们常常根本得不到执行: - **工具过于分散。** Semgrep、Trivy、Checkov、OSV-Scanner 和 ZAP 各自拥有独立的 CLI、flags 和 JSON 数据结构,仅仅阅读五种不同的报告格式就已经是一项繁重的任务。 - **想要统一视图的仪表板却盯着你的代码。** 大多数*能够*聚合结果的工具都是 SaaS:你需要上传源代码、按席位付费,并消耗 CI 分钟数才能看到结果。 - **结果最终四处散落。** 即使你运行了所有扫描,各项检测结果也只是留在五个终端的输出中,没有统一的严重性评级标准,没有历史记录,也没有一个统一的地方来对它们进行筛选排查。 这里的目标是让完整的本地安全扫描只需**一个命令(或一次点击)**即可完成。每个扫描器都位于同一个接口之后,每个结果都被标准化为统一的 schema,并由同一个仪表板全面展示——所有操作都在你的机器上完成,源代码和扫描结果永远不会离开你的设备。将其指向一个文件夹、URL 或容器镜像,即可在一个地方查看结果。CLI 适合集成到 CI 中;而桌面应用则无需终端即可运行相同的扫描。 [日本语版 README 请点击这里 →](./README.ja.md) · [GitHub](https://github.com/0xkaz/devsec-scanner) ## 截图 | 结果(摘要 + 扫描项) | 扫描(文件夹 / URL / 镜像) | | ---------------------------------------- | ---------------------------------------- | | ![Results](https://static.pigsec.cn/wp-content/uploads/repos/cas/ac/ac0f2ec978546f0e63e544af762430c9b35f9ac5cd9094986d0f6007e1611688.png) | ![Scan](https://static.pigsec.cn/wp-content/uploads/repos/cas/65/656f7798e53ab83ba60e13443e0368b1cbdee00fedf5ba2436a579a241cc5343.png) | | **历史记录(趋势 + 过去运行记录)** | **扫描指南** | | ![History](https://static.pigsec.cn/wp-content/uploads/repos/cas/cf/cf260eed0fcfe51b137a87d0a6001f1496ba7a2432e953d8d5e75733edcfd550.png) | ![Scan Guide](https://static.pigsec.cn/wp-content/uploads/repos/cas/19/198d41d8f8128509c5b3a05fab37931f889226cb84d3a84f9b5bc28a49ffb034.png) | | **扫描项详情** | **日语界面 (i18n)** | | ![Finding detail](https://static.pigsec.cn/wp-content/uploads/repos/cas/7e/7e22f99836e2c3679b3f0a4d6cf497404375cb902920acf4cfd23d101996735f.png) | ![Japanese UI](https://static.pigsec.cn/wp-content/uploads/repos/cas/83/83ebe504b954b93686865c5de267cb94211b5b2eba9411d21f0b4d2e20781b4e.png) | | **设置 (Socket.dev key)** | **扫描进行中(开关 + 取消)** | | ![Settings](https://static.pigsec.cn/wp-content/uploads/repos/cas/7a/7acbcbe0c89faecae44357c3d7dbe8706b78ff36d331ca5325e6eae6fa84eb41.png) | ![Scanning](https://static.pigsec.cn/wp-content/uploads/repos/cas/de/de88edc73abf66d43208347ba8c09459e710dc51df9f15d8621d974ce1daf7bf.png) | ## 扫描范围 | 类别 | 全称 | 检查内容 | 工具 | | ------------ | ------------------------------------ | ----------------------------------------------------------------------- | ------------------ | | SAST | 静态应用安全测试 | 静态扫描源代码以查找易受攻击的模式 | Semgrep | | SCA | 软件成分分析 | 依赖项中已知的 CVE | Trivy `fs` | | IaC | 基础设施即代码 | 基础设施定义中的错误配置 | Checkov | | DAST | 动态应用安全测试 | 通过发起攻击来检测正在运行的应用 | OWASP ZAP | | Secret | 密钥扫描 (Secret scanning) | 硬编码的凭据、token 和 keys | Trivy | | Image | 容器镜像扫描 | 构建好的镜像中的操作系统和软件包漏洞 | Trivy `image` | | Supply chain | 供应链分析 | 依赖项与 OSV 漏洞数据库的对比 | OSV-Scanner | | Supply risk | 供应链风险 | 安装脚本和未锁定的依赖项(本地);配合 key 进行的行为分析 | Socket.dev / local | 文件系统扫描(`make scan`)会同时运行 SAST + SCA + IaC + secret + supply-chain + supply-risk;DAST(`--url`)和容器镜像(`--image`)扫描则按需运行。每个扫描器原生的 JSON 输出都会被标准化为统一的 `Finding` 格式,并聚合成一个 `scan-report.json` 供仪表板读取。 ### 静态与动态 - **除 DAST 外的所有扫描都是静态的。** SAST、SCA、IaC、secret、容器镜像和供应链扫描只会读取你的源代码、依赖项、基础设施配置或镜像,而不会运行任何内容——不会向目标发送流量,不需要应用处于运行状态,并且它们绝对不会执行被扫描的代码,因此不会产生任何副作用。 - **DAST 是动态的。** 它会驱动一个*正在运行的*应用并发送真实的请求。这能找出运行时的问题,但可能会对目标产生副作用,因此请仅扫描你拥有或被授权测试的系统。 ### DAST:基线扫描与主动扫描 本项目运行的是 **ZAP 基线(被动)**扫描:它会抓取网站并检查响应内容(缺失的安全标头、cookie flags、信息泄露)。其影响较低,因此即使在生产环境中运行也是合理的。 而**完整 / 主动**扫描(此处默认不运行)会注入攻击 payload(SQLi、XSS 等)来确认可利用的漏洞。这种方式极具侵入性——它可能会创建或删除数据、发送邮件或对目标造成负载——因此请仅限于在**预发环境或你自己拥有的系统**中使用,并尽量仅针对测试环境使用经过身份验证的标头(`--auth-header`)。 ## 架构 ``` pnpm workspace ├── packages/core # Zod schema + types for the unified report (shared) ├── packages/cli # Orchestrates the Docker-based scanners, writes the report └── packages/web # React + Vite dashboard that visualizes the report ``` 有关数据流、可替换部件(接缝)以及支持的运行模式(本地 CLI、Web 查看器、桌面应用和计划中托管的模式),请参阅 [`docs/architecture.md`](./docs/architecture.md)。 ## 前置条件 - **Node.js** ≥ 20 和 **pnpm** ≥ 9 - 在本地运行的 **Docker**(Desktop 或 Engine)—— 扫描器作为容器运行 ## 快速开始 ``` pnpm install # install workspace dependencies cp .env.example .env # adjust scan target / output path if needed make scan # run the static suite (SAST + SCA + IaC + secret + supply) make dev # open the dashboard (http://localhost:5174) ``` `make scan` 会将统一报告写入 `SCAN_REPORT_PATH` 指定的路径(默认为 `packages/web/public/scan-report.json`),仪表板在启动时会加载该文件。仓库中附带了一个示例报告,因此仪表板在首次运行时就会有数据展示。 ## 命令 你可以单独运行扫描器,也可以全部一起运行: ``` make scan # SAST + SCA + IaC + secret + supply-chain (the static suite) make scan-sast # Semgrep only make scan-sca # Trivy only (dependency CVEs + secrets) make scan-iac # Checkov only (skipped automatically when no *.tf files exist) make scan-supply # OSV-Scanner only (supply-chain) make scan-socket # supply-chain risk (local; Socket.dev with SOCKET_API_KEY) make scan-dast # OWASP ZAP baseline — requires a target URL make scan-image IMAGE=nginx:1.25 # Trivy container-image scan ``` `make scan` 会运行完整的静态扫描套件;`scan-dast`(需要提供 URL)和 `scan-image`(需要提供镜像)是按需启用的。 DAST 之所以是可选的,是因为它需要一个正在运行的目标: ``` DAST_TARGET_URL=http://host.docker.internal:3000 make scan-dast ``` DAST 还支持多个逗号分隔的目标,以及处于身份验证保护下的扫描(标头会通过 ZAP 的 replacer 注入到每个请求中): ``` pnpm --filter @devsec/cli scan -- --only dast \ --url http://host.docker.internal:3000,http://host.docker.internal:8080 \ --auth-header "Bearer eyJhbGci..." ``` 想看看它是如何发现真实漏洞的吗?仓库中内置了一个故意留下漏洞的目标,请见 [`examples/vulnerable-app`](./examples/vulnerable-app): ``` make scan SCAN_TARGET_DIR=examples/vulnerable-app ``` 开发与质量检测: ``` make dev # Vite dev server for the dashboard make build # build all packages make lint # ESLint + Prettier check make test # Vitest unit/integration suite (no Docker needed) make integration # Real-scanner tests via Docker (Semgrep/Trivy/Checkov) make e2e # Playwright browser tests make typecheck # tsc --noEmit across packages make help # list all targets ``` CLI 也支持直接传递 flags: ``` pnpm --filter @devsec/cli scan -- \ --target ./my-project \ --only sast,sca \ --out ./scan-results/report.json \ --url http://host.docker.internal:3000 # 扫描 container image pnpm --filter @devsec/cli scan -- --only image --image nginx:1.25 ``` 可供选择的 `--only` 类型包括:`sast, sca, iac, dast, image, supply, socket`(secret 由 `sca` 扫描输出)。当设置了 `SOCKET_API_KEY` 时,`socket` 扫描会加入 Socket.dev 行为分析(在桌面应用中通过 **Settings** 进行设置);否则它只会运行本地启发式检测。 ## 在本地进行验证 以下是一个能让你看到从端到端完整工作流程的快速步骤: 1. **扫描内置的漏洞目标并打开仪表板:** make scan SCAN_TARGET_DIR=examples/vulnerable-app make dev 2. **探索** Results 视图(摘要 + 扫描项表格),打开某个扫描项查看详情,并阅读扫描指南。 3. **构建趋势:** 多次重新扫描(修复一些问题,或者指向另一个项目)。每次运行都会被追加到 **History** 标签页中,这样你就可以观察严重性统计数据随时间的变化。 4. **安全地尝试 DAST**,在你拥有的目标上进行(基线扫描是被动的): DAST_TARGET_URL=http://host.docker.internal:3000 make scan-dast 5. **运行质量门禁:** make lint && make test # 运行快,不需要 Docker make integration # 运行真实的扫描器(需要 Docker) make e2e # 运行浏览器测试 ## 应用介绍 - **Scan** —— 输入一个本地文件夹(SAST/SCA/IaC/secret/supply-chain)、URL(DAST)或容器镜像,即可从 UI 运行扫描;你也可以将现有的 `scan-report.json` 拖放至此进行查看。这需要原生运行程序,因此扫描功能在[桌面应用](./docs/desktop.md)中处于激活状态;而在浏览器中,它只会显示指南和上传框。 - **Results** —— 页面上展示单次扫描内容:可视化摘要(总计、严重性环形图、按类型统计的扫描项柱状图、各扫描器状态),其后是一个可排序、可过滤的表格,并带有详情抽屉(文件/行号、CVE/CWE、包、修复建议)。点击摘要卡片或扫描器行,即可缩小下方表格的显示范围。浏览器会在这里打开;桌面应用则是通过点击某次扫描或历史记录跳转至此。 - **History** —— 展示过往运行中各严重性级别的扫描项趋势,以及包含每次扫描记录的表格(点击即可重新打开)。CLI 会将每次 `make scan` 的结果追加到本地基于文件的 history 存储中(`history/index.json` 以及每次运行一个独立文件);桌面应用则将其运行的扫描记录保存在 `localStorage` 中。不需要使用数据库,并且索引结构的设计与未来托管的 `scan_runs` 表保持一致。 - **Scan Guide** —— 解释了每一个类别(SAST、DAST、SCA、IaC、secret、容器镜像、供应链、供应链风险),并为每个类别生成可复制粘贴的 CLI 命令(DAST 命令会随着你输入目标 URL 而实时更新)。 - **Settings**(桌面版)—— 存储 Socket.dev API key,以便在供应链风险扫描中加入行为分析;该 key 仅保存在本地,并在扫描时传递使用。 ## 统一报告格式 报告的格式如下所示: ``` { "schemaVersion": "1", "generatedAt": "2026-06-30T09:15:00.000Z", "target": "demo-app", "scanners": [ { "scanner": "semgrep", "type": "sast", "status": "ok", // ok | skipped | error "durationMs": 8421, "findings": [ { "id": "semgrep:...:src/db/query.ts:42", "scanner": "semgrep", "type": "sast", "ruleId": "...tainted-sql-string", "title": "tainted-sql-string", "severity": "high", // critical | high | medium | low | info | unknown "message": "...", "file": "src/db/query.ts", "startLine": 42, "cwe": ["CWE-89: SQL Injection"], "remediation": "Use parameterized queries.", }, ], }, ], "summary": { "total": 13, "bySeverity": { "...": 0 }, "byType": {}, "byScanner": {}, }, } ``` ## CI 仓库中附带了两个 GitHub Actions 工作流: - **`.github/workflows/ci.yml`** —— 在每次 push 和 PR 时执行质量门禁检查(lint → type-check → test → build)。 - **`.github/workflows/security-scan.yml`** —— 运行相同扫描器的参考流水线(Semgrep、Trivy、Checkov、OSV-Scanner,以及按需运行的 ZAP)。它默认使用 `workflow_dispatch`(手动触发),因此它本身绝不会消耗 Actions 分钟数 —— 你可以在实际项目中将其切换为 `push` / `pull_request` 以限制代码合并。 ## 运行环境 扫描器作为 Docker 容器运行,因此 CLI 需要一台装有 Docker daemon 的主机: - **本地环境(默认)。** 在你的机器上运行 `make scan` —— 你的源代码和扫描结果永远不会离开本地。其对外网络流量仅限于拉取扫描器镜像及其漏洞数据库,以及针对公共漏洞 API 进行的依赖项查询:OSV-Scanner 默认会带着包名/版本号查询 OSV.dev(同时也提供离线数据库模式),而 Socket.dev 供应链风险检查是可选的(除非你设置了 key,否则默认关闭)。它们都不会发送你的源代码。 - **装有 Docker 的虚拟机**(例如小型的云虚拟机 / Fly.io machine)。CLI 无需任何更改即可正常工作,因为它依然可以启动同级容器。 ## 适用范围 这是一个有明确重心的演示项目。**属于范围内:** CLI、统一报告、仪表板以及参考 CI 工作流。**不在范围内:** 从 Web UI 运行扫描、身份验证、SIEM/告警集成以及生产环境监控。 ## 许可证 [MIT](./LICENSE)
标签:AI应用开发, DevSecOps, MITM代理, 上游代理, 安全扫描, 时序注入, 桌面应用, 特征检测, 自动化攻击, 请求拦截