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 包**。

## 主要特性
- **多生态系统支持**:审计:
- **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, 依赖管理, 无后门, 暗色界面, 逆向工具