tg12/phantomcreds
GitHub: tg12/phantomcreds
phantomcreds 是一个每日自动运行的 GitHub 扫描器,专门检测和追踪凭证采集及不安全凭证存储的开源仓库,通过多证据评分模型降低误报。
Stars: 0 | Forks: 0
phantomcreds
自动检测和追踪 GitHub 上凭证采集及不安全凭证存储仓库
JS Labs 项目 -
属于 AI Slop Intelligence 计划的一部分。
每日运行。对可疑仓库进行评分。捕获证据。仅在代码看起来可修复时才提交 issue。
## 为什么存在这个项目
这里反直觉的做法是克制。
这个项目的简单版本是一个巨型爬虫,标记每一个提到 `token`、`cookie` 或 `OAuth` 的仓库。这条路会立即失去信任,因为维护成本会超过信号价值。合法软件会存储令牌。合法工具会代理请求。合法集成会使用 OAuth 回调。
有用的版本则更窄:检测那些文档和代码共同暗示凭证采集、不安全持久化、重放姿态或暴露管理面的仓库。每天记录证据。仅在目标看起来仍然是一个可维护的软件项目而非明显的滥用工具包时才提交 issue。
这就是 **phantomcreds** 所做的。
它围绕一个前提构建:操作者的信任是核心产品。如果扫描器无法解释*为什么*一个仓库被标记以及*哪些代码行*导致了这一判断,它就还不完整。
## 它能做什么
**phantomcreds** 运行一个每日 GitHub Actions 任务,执行以下操作:
1. 搜索 GitHub 仓库中是否存在以下姿态短语:`multi-account`、`no API key needed`、`auth file`、`shared subscription`、会话复用、提供方中继,以及导入的浏览器认证语言
2. 跨 Go、Python、JavaScript 和 TypeScript 搜索凭证风险特征,如令牌或会话持久化、原始 `Authorization` 转发、管理认证绕过包装器、通配符管理暴露、绑定到 `0.0.0.0` 的回调监听器,以及已提交的含密钥的 `.env`、`.netrc`、`.pypirc`、Docker 认证配置、Terraform 凭证、私钥、服务账号和连接字符串材料
3. 直接从 GitHub API 获取目标高信号文件以及对类文本仓库文件的有界扫描
4. 根据仓库级证据模型对每个仓库评分,优先多族匹配而非单一查询噪声,然后偏向最近推送的非归档非 fork 仓库
5. 将仅追加的账本写入本仓库:
- [`data/repos.jsonl`](data/repos.jsonl) 用于每次仓库扫描结果
- [`data/findings.jsonl`](data/findings.jsonl) 用于含证据的具体发现
6. 自动更新 README 仪表板
7. 每个目标仓库最多开启或更新一个 issue,**仅当**发现具体且可修复时
8. 将明显的滥用导向仓库标记为 `report_only` 记录,而非向其大量提交 issue
无服务器。无数据库。无仪表板后端。
## 检测模型
扫描器结合四类证据:
| 证据类别 | 含义 |
|---|---|
| 采集姿态 | README 或描述中宣传共享订阅、中继、认证文件导入或"无需 API 密钥"的定位 |
| 凭证持久化 | 代码将类令牌材料写入本地认证文件或序列化会话存储 |
| 直接密钥暴露 | 当前仓库文件似乎包含已提交的云、模型提供方、CI、包注册表、webhook、SSH、服务账号、注册表认证、Terraform 或数据库连接凭证;证据在存储的发现和 issue 正文中被脱敏处理 |
| 不安全暴露 | 回调监听器广泛绑定、管理路由使用通配符 CORS,或认证绕过包装器削弱了控制面 |
| 集中泄露 | 请求日志或遥测路径似乎转发了含凭证的原始标头 |
并非每个命中都值得提交 issue。
产品规则是刻意的:
- `file_issue`:具有可辩护证据和合理维护者修复路径的具体技术缺陷
- `report_only`:仓库姿态看起来明显具有滥用性,或扫描可以证明风险但提交 issue 不太可能改善行为
- `watch`:存在可疑信号,但证据不足以进行自动化外部操作
这是主要的维护成本控制。它避免将每个可疑仓库都视为工作流目标。
## 代码异味与维护成本
三个令人不安的事实驱动了设计:
1. 最大的失败模式不是假阳性。而是证据薄弱的假阳性自动化。这比遗漏一个仓库更快地摧毁产品。
2. 仓库族比单个仓库更重要。一旦确认一个凭证采集代码库,下一步高杠杆操作是在衍生版本中搜索复用的路径和符号名称。
3. 项目应偏好仅追加的证据而非复杂的状态机。每日 JSONL 账本和确定性 README 更新比定制数据存储的维护成本更低。
### 魔鬼代言人的观点
舒适的答案是"扫描一切并提交一切"。
为什么这会失败:
- GitHub 代码搜索有速率限制且噪声大。
- 大多数提到令牌的仓库是正常软件。
- 对明显滥用仓库批量创建 issue 只会产生工作而不改变结果。
- 复杂的爬虫会增加故障面并降低操作者信心。
制胜之道更小:
- 搜索优先发现
- 多语言查询族
- 目标文件获取
- 仓库级评分
- 每个仓库最多一个 issue
- 对滥用严重的案例明确标记 `report_only`
这不那么戏剧化,但更持久。
## 以后你会后悔不知道的事
- 哪些仓库族克隆了相同的不安全凭证路径
- 哪些发现反复出现但不值得提交 issue
- README 姿态中的哪些措辞在代码确认之前就是领先指标
数据模型的结构使得这些问题可以在以后从账本中回答,而无需重新设计项目。
## 接下来要问的三个问题
1. 哪些克隆族特征在跨多个仓库反复出现后应从"有趣"升级为"硬性发现"?
2. 哪些 issue 类别实际上能带来维护者响应,哪些是应保持 `report_only` 的运营死胡同?
3. 在什么规模下 GitHub Search API 的噪声证明应添加本地语料库或计划种子列表?
## 实时仪表板
| 日期 | 已扫描 | 已标记 | 高风险 | 值得提交 Issue | 仅报告 | 新增高风险 |
|------|---------|---------|-----------|--------------|-------------|---------------|
| 2026-05-26 | 34 | 19 | 13 | 16 | 6 | 0 |
| 2026-05-25 | 39 | 20 | 11 | 17 | 5 | 0 |
| 2026-05-24 | 33 | 17 | 11 | 14 | 5 | 1 |
| 2026-05-23 | 33 | 18 | 14 | 17 | 9 | 0 |
| 2026-05-22 | 34 | 15 | 13 | 14 | 7 | 0 |
| 2026-05-21 | 33 | 18 | 12 | 17 | 7 | 0 |
| 2026-05-20 | 30 | 14 | 11 | 14 | 5 | 0 |
| 2026-05-19 | 55 | 21 | 14 | 16 | 7 | 1 |
| 2026-05-18 | 115 | 69 | 45 | 46 | 28 | 45 |
## 今日最高风险仓库
| 仓库 | 评分 | 发现数 | 操作 | Star 数 | 更新时间 |
|------|-------|----------|--------|-------|---------|
| fxzer/CLIProxyAPI | 1.000 | 8 | report_only | 0 | 2026-05-26 |
| router-for-me/CLIProxyAPI | 1.000 | 8 | report_only | 34812 | 2026-05-26 |
| NguyenSiTrung/CLIProxyAPI | 1.000 | 8 | report_only | 1 | 2026-05-25 |
| kaitranntt/CLIProxyAPIPlus | 1.000 | 8 | report_only | 106 | 2026-05-25 |
| kdjahdiel-code/c-pipe-engine | 1.000 | 7 | file_issue | 0 | 2026-05-25 |
| rituprodhan-ops/c-channel-engine | 1.000 | 7 | file_issue | 0 | 2026-05-25 |
| 6enta0/CPAplus | 1.000 | 7 | file_issue | 16 | 2026-05-24 |
| Sastraaaa/proxypilot | 1.000 | 7 | file_issue | 0 | 2026-04-29 |
| daishuge/playful-proxy-api-panel | 1.000 | 7 | report_only | 43 | 2026-05-25 |
| CodexNexor/VoltGate | 1.000 | 6 | file_issue | 4 | 2026-05-25 |
| kittors/CliRelay | 1.000 | 5 | file_issue | 742 | 2026-05-26 |
| traylinx/switchAILocal | 1.000 | 5 | file_issue | 2 | 2026-05-12 |
| jlcodes99/cockpit-tools | 0.770 | 3 | file_issue | 9262 | 2026-05-26 |
| SylphAI-Inc/AdalFlow | 0.560 | 2 | file_issue | 4151 | 2026-05-26 |
| Wei-Shaw/claude-relay-service | 0.410 | 2 | report_only | 11899 | 2026-05-26 |
| Work-Fisher/claude-codex-relay | 0.390 | 2 | watch | 0 | 2026-05-25 |
| xingkaixin/agent-dump | 0.390 | 2 | watch | 2 | 2026-05-24 |
| WrathZA/github-weld | 0.390 | 2 | watch | 0 | 2026-05-24 |
| YukiYonekura-321/famdish-backend-rails | 0.350 | 1 | file_issue | 1 | 2026-03-29 |
## 数据格式
**repos.jsonl** - 每次运行每个被扫描仓库一行:
```
{
"full_name": "owner/repo",
"composite": 0.82,
"classification": "high_risk",
"action": "file_issue",
"finding_count": 4,
"issue_worthy_count": 3,
"stars": 431,
"scan_date": "2026-05-18",
"created_at": "2026-04-29T20:14:00Z",
"updated_at": "2026-05-18T08:42:11Z",
"discovery_sources": ["auth-bypass", "callback-exposure", "shared-subscription-posture"],
"finding_types": ["callback_exposure", "credential_persistence", "management_auth_bypass"]
}
```
**findings.jsonl** - 每个具体发现一行:
```
{
"repo_full_name": "owner/repo",
"finding_type": "exposed_secret",
"title": "Secret-bearing credential material appears committed in current repository files",
"severity": "high",
"confidence": "confirmed",
"summary": "Current repository files appear to contain committed cloud, model-provider, CI, package-registry, webhook, SSH, or service-account credential material. Evidence is redacted in the report output.",
"issue_worthy": true,
"scan_date": "2026-05-18",
"evidence": [
".env:1 - OPENAI_API_KEY=[REDACTED:sk-pro...3456]",
"deploy/id_rsa:1 - [REDACTED:-----BEGIN OPENSSH PRIVATE KEY-----]"
]
}
```
## 设置
### 1. 创建或 Fork 仓库
本仓库在每次成功扫描后将自身账本提交回 `main` 分支。
### 2. 添加 GitHub PAT 密钥
创建一个具有以下权限范围的**经典** Personal Access Token:
- `public_repo`
- `read:user`
在以下位置将其添加为 `GH_TOKEN`:
**Settings -> Secrets and variables -> Actions -> New repository secret**
### 3. 启用 Actions
工作流在**英国时间每日 07:00** 运行,使用 `Europe/London` 时钟:
- 英国夏令时期间为 `06:00 UTC`
- 格林威治标准时间期间为 `07:00 UTC`
GitHub cron 仅支持 UTC,因此工作流在两个 UTC 小时都会触发,且仅当本地伦敦时间为 `07` 时才继续执行。
手动触发:
**Actions -> Daily Phantomcreds Scan -> Run workflow**
### 4. 本地运行
安全的本地测试运行:
```
git clone https://github.com/YOUR_USERNAME/phantomcreds.git
cd phantomcreds
python -m venv venv && source venv/bin/activate
pip install -e .[dev]
PHANTOMCREDS_LOCAL_MODE=1 GH_TOKEN=ghp_your_token phantomcreds
```
这使用相同的扫描逻辑在本地运行,但:
- 默认禁用外部 GitHub issue 创建
- 不重写主 `README.md`
- 将结果写入 `.local/phantomcreds/` 下
- 保持与托管运行相同的 GitHub API 获取、启发式评分和 issue 决策逻辑
生产级本地运行:
```
GH_TOKEN=ghp_your_token \
PHANTOMCREDS_NOTIFY_EXTERNAL=1 \
PHANTOMCREDS_UPDATE_README=1 \
phantomcreds
```
有用的本地覆盖选项:
- `PHANTOMCREDS_OUTPUT_DIR=/tmp/phantomcreds-run`
- `PHANTOMCREDS_NOTIFY_EXTERNAL=0|1`
- `PHANTOMCREDS_UPDATE_README=0|1`
- `PHANTOMCREDS_REPORTS_FILE=/tmp/repos.jsonl`
- `PHANTOMCREDS_FINDINGS_FILE=/tmp/findings.jsonl`
- `PHANTOMCREDS_README_PATH=/tmp/README.md`
与 GitHub Actions 的运营差异:
- 相同的发现、获取、评分和通知代码路径
- 无调度器包装
- 除非设置了 `GITHUB_STEP_SUMMARY`,否则无 Actions 步骤摘要
- 本地模式是在允许外部 issue 创建之前测试扫描器变更的安全方式
## 假阳性与排除
如果一个仓库反复为良性但匹配了搜索姿态,将其添加到 [`data/allowlist.txt`](data/allowlist.txt),每行一个 `owner/repo`。列入白名单的仓库在后续运行中将被完全跳过。
扫描器在提出密钥发现之前还应用内置上下文过滤器:
- 脱敏的证据片段被忽略
- 测试、fixture 和文档路径不被视为活跃密钥暴露
- 如 `.env.example` 等模板文件包含占位符时不构成问题,但如果包含真实凭证材料仍会提出发现
- Docker 认证证据必须解码为可打印的 `user:password` 材料才被视为已提交密钥
- 凭证持久化发现需要附近的写入或序列化行为,而非仅 `session` 或 `cookie` 等词汇
这是一个仓库级扫描器。它不存储个人用户身份,也不尝试超越公开仓库内容进行归因。
标签:ETW劫持, IP 地址批量处理, OAuth令牌管理, Python, 仓库分析, 代码仓库监控, 凭证劫持, 凭证存储安全, 凭证收集, 子域名暴力破解, 安全扫描, 数据持久化风险, 无后门, 日志记录, 时序数据库, 时序注入, 漏洞自动化报告, 自动化检测