brunoevn/kevlar-checkdeps

GitHub: brunoevn/kevlar-checkdeps

一款零依赖的跨生态项目依赖扫描工具,用于检测过时版本、弃用包及安全漏洞,并可无缝集成至 CI/CD 流水线。

Stars: 5 | Forks: 0

# Kevlar CheckDeps (`kevlar.py`) 一个使用 Python 编写的强大、快速且自包含的命令行实用程序,用于扫描项目依赖。它通过查询包注册表(npm/PyPI/NuGet/Packagist/Maven Central/Go Proxy/crates.io/RubyGems)和 Google OSV(Open Source Vulnerabilities)数据库,识别**过时版本**、**弃用通知**(已撤回的包)以及**安全漏洞**。 该工具采用模块化和可扩展的架构设计,支持检查直接和传递依赖,并且**无需安装任何外部 Python 包**。 ![Kevlar CheckDeps 仪表盘](https://static.pigsec.cn/wp-content/uploads/repos/cas/eb/eb76a93fc2279c01cd686f4d025db44ddd593e0a6b1e7cdc944f8c6963c05037.png) ## 主要特性 - **多生态系统支持**:审计: - **Node.js (`npm`)**:支持 `package.json`、`package-lock.json`、Yarn `yarn.lock` 和 pnpm `pnpm-lock.yaml`。 - **Python (`pip`)**:支持 `requirements.txt`、Poetry `poetry.lock` + `pyproject.toml`、Pipenv `Pipfile.lock` 和 PDM `pdm.lock`。 - **.NET (`nuget`)**:支持 C# `.csproj`、VB.NET `.vbproj`、F# `.fsproj`、Solution 文件 (`.sln`) 以及 Central Package Management (`Directory.Packages.props`)。 - **PHP (`php`)**:支持 `composer.json` 和 `composer.lock`。 - **Java (`maven`)**:支持多模块 ``、集中式 `` 以及递归的父 POM 属性/依赖继承。 - **Java/Kotlin (`gradle`)**:支持 `build.gradle`、`build.gradle.kts`、`gradle.lockfile` 和 Version Catalogs `libs.versions.toml`。 - **Android (`android`)**:优先使用 Google 的 Maven Registry 获取 Android 库。 - **Go (`go`)**:支持 `go.mod`。 - **Rust (`rust`)**:支持 `Cargo.toml` 和 `Cargo.lock`。 - **Ruby (`ruby`)**:支持 `Gemfile` 和 `Gemfile.lock`。 - **过时包检测**:将已安装的版本与注册表中的最新版本进行比较,将更新分类为 `Major`、`Minor` 和 `Patch` 级别。 - **弃用警告**: - 对于 `npm`:提取已安装确切版本维护者的弃用通知。 - 对于 `pip`:识别并报告 PyPI 上“yanked”(已弃用/撤回)的发布。 - 对于 `rust`:识别并报告 crates.io 上“yanked”的 crate。 - **安全漏洞审计**:查询公共 Google OSV 数据库以识别活跃的安全漏洞,包括 CVE/GHSA ID、CVSS 向量和咨询摘要。 - **传递父级追踪**: - 对于 `npm`:从 `package-lock.json`、Yarn `yarn.lock` 或 pnpm `pnpm-lock.yaml` 递归构建依赖图。 - 对于 `pip`:从 lockfile(`poetry.lock`、`Pipfile.lock`、`pdm.lock`)或 `requirements.txt` 中的 `# via parent_name` 注释解析传递依赖。 - 对于 `nuget`:从 `obj/project.assets.json` 重建父子图。 - 对于 `php`:从 `composer.lock` 重建父子图。 - 对于 `go`:将 `go.mod` 中的 indirect 包标记为传递依赖。 - 对于 `rust`:从 `Cargo.lock` 重建父子图。 - 对于 `ruby`:从 `Gemfile.lock` 重建父子图。 - 在报告中清晰标注传递依赖包(例如:`Transitive (via Newtonsoft.Json)`)。 - **快速执行**:使用 Python 的 `concurrent.futures.ThreadPoolExecutor` 并发执行网络请求。 - **高性能扫描**:通过向 npm 请求缩写的元数据格式标头来优化查询,并在单个 `POST /v1/querybatch` 请求中检查安全公告,而不是逐一查询。 - **可视化控制台报告**:在整洁、带颜色的表格中显示扫描结果及汇总统计数据。 - **终端兼容性回退**:自动检测标准终端的编码能力,无缝从 Unicode 字符切换至整洁的 ASCII 边框,以防止 Windows 控制台发生编码崩溃。 - **JSON 和 Markdown 导出**:支持将结果导出为格式化的 Markdown 表格或原始 JSON 数据集,以便集成到 CI/CD pipeline 中。 ## 安装与环境要求 - **Python**:3.6 或更高版本。 - **零依赖**:该脚本**仅依赖 Python 标准库**(`urllib.request`、`concurrent.futures`、`json`、`argparse`、`sys`、`re`、`unicodedata`、`xml.etree.ElementTree`)。无需执行 `pip install`! 要开始使用,只需下载/克隆工作区并运行脚本: ``` python kevlar.py --help ``` ## 如何使用 ### 1. 基础扫描(仅限直接依赖) 通过 `--tech`(或 `-t`)指定目标生态系统,并通过 `--path`(或 `-p`)指定目录: - **对于 Node.js (npm)**: python kevlar.py --tech npm --path ./nodejs_project - **对于 Python (pip)**: python kevlar.py --tech pip --path ./python_project - **对于 .NET (nuget)**: python kevlar.py --tech nuget --path ./dotnet_project - **对于 PHP (php)**: python kevlar.py --tech php --path ./php_project - **对于 Java (maven)**: python kevlar.py --tech maven --path ./java_project - **对于 Go (go)**: python kevlar.py --tech go --path ./go_project - **对于 Rust (rust)**: python kevlar.py --tech rust --path ./rust_project - **对于 Ruby (ruby)**: python kevlar.py --tech ruby --path ./ruby_project - **对于 Java/Kotlin (gradle)**: python kevlar.py --tech gradle --path ./gradle_project - **对于 Android (android)**: python kevlar.py --tech android --path ./android_project ### 2. 扫描安全漏洞 添加 `--vuls`(或 `-v`)标志以针对 Google OSV 数据库审计包: ``` python kevlar.py --tech nuget --path ./dotnet_project --vuls ``` ### 3. 扫描所有依赖(直接 + 传递) 添加 `--all`(或 `-a`)标志以扫描 lockfile/assets 中解析出的整个依赖树: - **对于 Node.js (npm)**: python kevlar.py --tech npm --path ./nodejs_project --all --vuls - **对于 .NET (nuget)**: python kevlar.py --tech nuget --path ./dotnet_project --all --vuls - **对于 PHP (php)**: python kevlar.py --tech php --path ./php_project --all --vuls - **对于 Rust (rust)**: python kevlar.py --tech rust --path ./rust_project --all --vuls - **对于 Ruby (ruby)**: python kevlar.py --tech ruby --path ./ruby_project --all --vuls *(对于 pip,如果您的 `requirements.txt` 包含来自 `pip-compile` 的传递注释,脚本将自动解析并显示父级追踪详情。)* *(对于 Java / Maven,如果您将路径指向父级 POM,脚本将自动递归发现并聚合所有子模块。)* ### 4. 导出报告文件 使用 `--output`(或 `-o`)将结果输出为结构化的 Markdown(`.md`)、原始 JSON(`.json`)或交互式 HTML 仪表盘(`.html`)文件: - **对于 Markdown**: python kevlar.py --tech nuget --path ./dotnet_project --vuls --output dependency_report.md - **对于交互式 HTML**: python kevlar.py --tech nuget --path ./dotnet_project --vuls --output dependency_report.html ### 5. 显示最新包 默认情况下,该工具仅显示存在问题的包(过时、弃用、漏洞或报错)。使用 `--show-all` 列出所有包: ``` python kevlar.py --tech nuget --path ./dotnet_project --show-all ``` ### 6. 检查更新 检查 GitHub 上是否有可用的新版本 Kevlar: ``` python kevlar.py --update ``` ## CLI 参数参考 ## | 参数 | 简写 | 默认值 | 描述 | | --- | --- | --- | --- | | `--tech` | `-t` | *必填* | 要检查的包管理器/技术。选项:`npm`、`pip`、`nuget`、`php`、`maven`、`go`、`rust`、`ruby`、`gradle`、`android`。 | | `--path` | `-p` | `.` | 包含包文件的目录(例如 `.csproj`、`composer.json`、`package.json`、`pom.xml`、`go.mod`、`requirements.txt`、`Cargo.toml`、`Gemfile`、`build.gradle`、`libs.versions.toml` 等)。 | | `--vuls` | `-v` | `False` | 通过 Google OSV API 启用安全漏洞查询。 | | `--all` | `-a` | `False` | 扫描 lockfile 中解析出的所有依赖,而不仅仅是直接依赖。 | | `--concurrent` | `-c` | `10` | 要运行的并发网络请求线程数。 | | `--output` | `-o` | `None` | 导出报告文件的路径(自动检测 `.json`、`.md` 和 `.html` 格式)。 | | `--show-all` | | `False` | 显示所有依赖,包括那些已是最新且安全的依赖。 | | `--fail-on-vulns` | | `None` | 在发现安全问题时中断构建(退出代码为 1)。接受阈值限制(例如:`"critical:2,high:4"`)。 | | `--suppress` | `-s` | `None` | 包含漏洞抑制规则的 JSON 文件路径(默认:在活动路径中查找 `kevlar-suppressions.json`)。 | | `--update` | | `False` | 从 GitHub 检查更新。 | ## CI/CD Pipeline 集成与构建中断 对于安全审计,您可以使用 `--fail-on-vulns` 标志,在发现漏洞时自动以状态 `1` 退出(导致 pipeline 构建失败)。 ### 构建中断策略 1. **存在任何漏洞即失败**: 直接传递不带值的参数,默认表示只要存在至少一个漏洞就会失败: python kevlar.py --tech pip --path ./project --vuls --fail-on-vulns 2. **自定义严重程度阈值(或逻辑)**: 以逗号分隔的 `severity:limit` 列表形式指定确切的严重程度限制。如果违反了**任何**限制,构建即中断: - 如果存在**至少 2 个 critical** 漏洞则中断: python kevlar.py --tech pip --path ./project --vuls --fail-on-vulns "critical:2" - 如果存在**至少 2 个 critical 或 4 个 high** 漏洞则中断: python kevlar.py --tech pip --path ./project --vuls --fail-on-vulns "critical:2,high:4" 有效的严重程度标识符:`critical`、`high`、`medium`、`low`、`unknown`。(CVSS 向量字符串会被动态解析以提取分数并映射到这些级别:Critical $\ge 9.0$、High $\ge 7.0$、Medium $\ge 4.0$、Low $\ge 0.1$)。 ### Pipeline 示例 #### 1. GitHub Actions (`.github/workflows/dependency-scan.yml`) 您可以运行脚本并将 JSON 报告发布为构建产物 (artifact): ``` name: Dependency Vulnerability Audit on: push: branches: [ main ] pull_request: branches: [ main ] jobs: audit: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.10' - name: Run Dependency Checker run: | python kevlar.py --tech npm --path ./ --vuls --fail-on-vulns "critical:1,high:3" --output report.json - name: Upload Scan Report uses: actions/upload-artifact@v4 if: always() with: name: dependency-audit-report path: report.json ``` #### 2. GitLab CI (`.gitlab-ci.yml`) 在 Python 环境中运行扫描器,导出 JSON 报告,并将其作为作业产物 (artifact) 上传: ``` stages: - test dependency_scan: stage: test image: python:3.10-slim script: # Run audit, failing if there is at least 1 critical or 3 high vulnerabilities - python kevlar.py --tech nuget --path ./ --all --vuls --fail-on-vulns "critical:1,high:3" --output report.json artifacts: name: "dependency-audit-report" expose_as: "Dependency Audit Report" when: always paths: - report.json ``` ## 漏洞抑制(忽略警报) 您可以抑制特定的漏洞警报,以防止它们中断您的构建 pipeline。创建一个 JSON 文件(默认为项目目录下的 `kevlar-suppressions.json`)来包含您的规则: ``` { "suppressions": [ { "id": "GHSA-pq67-6m6q-mj2v", "reason": "Redirecciones no deshabilitadas en PoolManager mitigadas en nuestro código." }, { "package": "certifi", "reason": "Librería de certifi utilizada únicamente en entorno local/testeo." }, { "package": "django", "id": "GHSA-2gwj-7jmv-h26r", "reason": "Inyección SQL mitigada por nuestro uso del ORM nativo seguro." } ] } ``` 规则支持: - 在所有包中全局抑制基于漏洞 ID(CVE 或 GHSA)的警报。 - 抑制整个包的漏洞。 - 抑制特定包上的特定漏洞 ID。 ## 设计考量与行为 ### 1. 性能优化 - **并发**:使用 Python 的 `concurrent.futures.ThreadPoolExecutor` 并发执行包元数据的注册表查询。默认情况下,它使用 `10` 个线程运行,可以通过 `--concurrent` 进行调整。 - **简化的 npm 元数据**:对 npm 注册表的查询会请求简化的包元数据格式(`application/vnd.npm.install-v1+json`),从而将 HTTP 响应的 payload 大小减少 95% 以上- **漏洞查询批处理**:对 Google OSV API 的查询以大型 POST 批次(`/v1/querybatch`)执行,每个请求最多 1000 个包,避免了多次缓慢的单独 API 往返。 - **可配置的端点**:所有外部注册表和漏洞 API 的端点均被定义为 [kevlar.py](kevlar.py) 顶部的配置变量,以便于自定义。 ### 2. 版本比较逻辑 为了正确标记过时的包,该工具运行了一个自定义的语义化版本解析器,支持: - 最多 4 位版本段数字(例如 `1.2.3.4`)。 - 将更新分类为 `Major`(破坏性更新)、`Minor`(向后兼容的新功能)和 `Patch`(缺陷修复)。 - 在更新分类期间自动忽略预发布版本元数据。 - 在继承 CPM 版本标签时,对 C# 和 VB.NET 中央包依赖项进行精确映射。
标签:LNA, Python, 依赖管理, 无后门, 暗色界面, 逆向工具