LeoZhengKai/ossvet
GitHub: LeoZhengKai/ossvet
ossvet 是一款本地 CLI 工具,通过纯静态分析在不执行任何代码的前提下,对公开 GitHub 仓库进行克隆前的供应链安全信任评估。
Stars: 0 | Forks: 0
# ossvet
[](https://github.com/LeoZhengKai/ossvet/actions/workflows/ci.yml)
[](LICENSE)
`ossvet` 是一个本地 CLI 工具,帮助你在 clone、安装或运行某个仓库之前,**评估其是否值得信任**。
它会将仓库浅克隆到一个临时的临时目录中,并行运行一系列静态扫描器,并为你提供一个最终的判定结果:
```
╭──────────────── OSS Vet Report ─────────────────╮
│ Repo: https://github.com/some-org/some-pkg │
│ Commit: a3f7b2c91d04 │
│ Verdict: BLOCK / DO NOT RUN LOCALLY │
│ Score: 82 / 100 │
│ Duration: 4.1s │
│ │
│ Top Findings: │
│ 1. Bidirectional Unicode control character │
│ 2. Reverse-shell pattern in src/util.py:44 │
│ 3. package.json postinstall script │
│ 4. Possible typosquat: `requestes` │
╰─────────────────────────────────────────────────╯
```
它会生成三个可供你阅读或提交的报告文件:
| 文件 | 内容 |
|------|----------|
| `reports/report.md` | 易读的检查结果、扫描器表格、建议 |
| `reports/report.json` | 完整的结构化结果(可通过 jq、CI 脚本等处理) |
| `reports/SKILL.md` | 安全通行证 —— 锁定 commit hash,随依赖一并提交的检查清单 |
**它绝不会执行被扫描仓库中的任何一行代码。**
## 安装说明(一次性)
`ossvet` 是一个 Python CLI。只需安装一次,即可在整个系统中使用:
```
# Option A — pipx(推荐:隔离环境,无依赖冲突)
pipx install git+https://github.com/LeoZhengKai/ossvet
# Option B — pip 安装到你的当前环境
pip install git+https://github.com/LeoZhengKai/ossvet
# Option C — 从源码进行 dev install
git clone https://github.com/LeoZhengKai/ossvet
cd ossvet
pip install -e .
```
安装完成后,`ossvet` 命令可以在你机器上的**任何目录**下运行 —— 你不需要处于 `ossvet` 的源码文件夹中。
## 快速开始
```
# 1. 检查已安装的内容
ossvet doctor
# 2. Vet 一个 repo(fast mode,约 5 秒)
ossvet scan https://github.com/some-org/some-package
# 3. 使用所有 scanners Vet 一个 repo(deep mode,约 60–120 秒)
ossvet scan https://github.com/some-org/some-package --deep
# 4. Vet 磁盘上已有的内容(一个目录或已下载的 .zip)
ossvet scan-local ./some-package # or: ossvet scan-local some-package.zip
```
## 两种扫描模式
### 快速模式(默认) —— 约 5 秒,无需外部工具
运行五个纯 Python 扫描器,用于捕获最危险的模式:
| 扫描器 | 捕获内容 |
|---------|-----------------|
| `risky_files` | postinstall 脚本、setup.py 钩子、.vscode/tasks.json 可执行文件、CI workflow 风险 |
| `patterns` | curl-pipe-sh、反向 shell、混淆的 eval/exec、针对凭据的攻击、时间炸弹 |
| `unicode_trojan` | CVE-2021-42574 Trojan Source —— 不可见的 BIDI 字符、零宽字符、西里尔字母同形异义字 |
| `dependency_hygiene` | Typosquat(拼写错误)的包名、未锁定的依赖、非官方注册源的依赖 |
| `provenance` | 新注册的维护者账号、单人贡献者、长期未更新的仓库、Star 数量激增 |
```
ossvet scan https://github.com/org/repo # fast by default
```
### 深度模式 (--deep) —— 约 60–120 秒,需要外部工具
还会运行专业级工具:
| 扫描器 | 捕获内容 |
|---------|-----------------|
| `semgrep` | 静态分析(锁定 `p/default` + `p/supply-chain` 规则集) |
| `syft` + `grype` | 对所有声明的依赖进行 CVE 审计 |
| `gitleaks` | 提交到 git 历史记录中的密钥和凭据 |
| `scorecard` | OpenSSF 供应链健康检查 |
| `modelscan` | 基于 Pickle 的 ML 权重文件(加载时会导致任意代码执行) |
```
ossvet scan https://github.com/org/repo --deep
```
## 安装深度扫描工具
```
# macOS — 让 ossvet 替你完成:
ossvet doctor --fix
# 或者手动进行:
brew install semgrep syft grype gitleaks ossf/scorecard/scorecard
pip install modelscan
```
`ossvet doctor` 会准确显示哪些工具已安装、哪些缺失。每个缺失的工具都会优雅降级 —— 快速扫描器始终会运行。
## 完整用户工作流
### 在引入新依赖之前
```
# 在 pip install / npm install 之前的快速检查
ossvet scan https://github.com/org/package
# 如果 verdict 为 LOW RISK → 继续
# 如果 verdict 为 REVIEW REQUIRED → 在决定前阅读 reports/report.md
# 如果 verdict 为 BLOCK → 不要在你的机器上安装
```
### 在将依赖合并到生产环境之前进行深度审计
```
ossvet scan https://github.com/org/package --deep --output-dir reports/audits/package-name
# 将 reports/audits/package-name/SKILL.md 作为 security passport 提交到你的 repo 中
```
### CI 门禁 —— 如果依赖存在风险则使构建失败
```
# 在你的 CI pipeline 中:
ossvet scan https://github.com/org/package --fail-on=review
# 如果 verdict 为 REVIEW 或更糟,则 exit code 为 1
```
## 判定与评分
| 分数 | 判定结果 | 含义 |
|-------|---------|---------|
| 0–24 | **低风险** (绿色) | 未发现重大问题 |
| 25–59 | **需要审查** (黄色) | 在引入前值得查阅的问题 |
| 60–100 | **阻止** (红色) | 请勿在你的机器上安装或运行 |
**强制覆盖规则:无论得分多少,以下情况一律强制标记为“阻止 (BLOCK)”:**
- 双向 Unicode 控制字符(Trojan Source 攻击)
- 反向 shell 特征
- 加密货币挖矿程序特征
- ML 权重文件中出现 ModelScan CRITICAL 级别的检查结果
## 所有参数
```
ossvet scan [OPTIONS]
```
| 参数 | 默认值 | 描述 |
|------|---------|-------------|
| `--deep` | off | 同时运行外部扫描器(semgrep、grype 等) |
| `--output-dir` | `reports` | 报告文件的写入位置 |
| `--fail-on` | `block` | 如果判定结果 ≥ `low`/`review`/`block`,则退出码为 1 |
| `--no-api` | off | 跳过 GitHub API 调用(不进行 provenance 或 scorecard 检查) |
| `--keep-clone` | off | 扫描完成后不删除临时克隆目录 |
| `--timeout` | `60` | 每个扫描器子进程的超时时间(秒) |
| `--skip` | – | 要跳过的扫描器名称,例如 `--skip semgrep` |
| `--only` | – | 仅运行列出的扫描器,例如 `--only patterns` |
## 退出码
| 代码 | 含义 |
|------|---------|
| `0` | 扫描完成;判定结果低于 `--fail-on` 阈值 |
| `1` | 扫描完成;判定结果达到或高于 `--fail-on` 阈值 |
| `2` | 扫描无法启动(克隆失败、URL 无效、达到大小限制) |
| `3` | 内部错误 |
## 安全保障
- **绝不执行仓库代码。** `setup.py` 会被解析为 AST,而不是直接运行。不执行任何 `pip install`、`npm install`、`make` 或脚本。
- **子进程调用:** 全部使用 `shell=False`、列表形式的参数,并设有严格的超时限制。
- **克隆隔离:** 始终克隆至 `tempfile.mkdtemp(prefix="ossvet-")`,并在退出时清理。
- **跳过二进制文件:** 采用空字节启发式检查;不对大于 2 MB 的文件进行模式扫描。
- **ANSI 注入防御:** 嵌入报告前,会去除所有外部工具输出中的 ANSI 字符。
- **在 Linux 上拒绝以 root 身份运行。**
## 开发
```
git clone https://github.com/LeoZhengKai/ossvet
cd ossvet
pip install -e ".[dev]"
pytest # run tests
ruff check ossvet/ # lint
mypy ossvet/ # type check
```
## 学习识别恶意代码
刚接触供应链攻击?[docs/threat-guide/](docs/threat-guide/) 是一份实践指南,教你**攻击者如何在仓库中隐藏恶意代码,以及如何识别它们** —— 安装钩子、Typosquat(域名/包名拼写错误)、pipe-to-shell、反向 shell、Unicode Trojan Source、时间炸弹以及可疑的依赖源。每种技术都链接到了一个已脱敏、无害的示例,供你自行扫描:
```
ossvet scan-local docs/threat-guide/examples --deep # → BLOCK, every category fires
```
阅读某个章节,预测哪个扫描器会捕获它,然后通过查看 `reports/report.md` 来检验你的判断。
## 路线图
| 版本 | 功能 |
|---------|---------|
| **v0.1** (当前) | 静态分析、快速 + 深度模式、丰富的终端输出 |
| **v0.2** | 动态沙箱 —— Docker 引爆测试、strace 系统调用追踪、网络流量捕获 |
| **v0.3** | LLM 推理层 —— Claude/GPT 自然语言执行摘要 + 误报分流 |
## 许可证
MIT —— 见 [LICENSE](LICENSE)。
标签:Blue Team, DNS 反向解析, Python, 云安全监控, 开源代码审计, 无后门, 逆向工具, 静态分析