CopyJosh/github-healthcheck
GitHub: beardwhocodes/github-healthcheck
一个基于 Cloudflare 平台构建的 GitHub 账户与仓库安全检测工具,用于识别恶意克隆仓库和账户冒充行为。
Stars: 0 | Forks: 0
## 功能简介
攻击者正在克隆真实的、受欢迎的代码库,并通过一个被投毒的 README 将其武器化。**GitHub Healthcheck** 能够找出它们——并找出那些冒充*您*的代码库。
| | |
| --- | --- |
| 🔬 **自我审计** | 根据此次攻击活动的指标,对您拥有的每个代码库进行评分。 |
| 🪪 **克隆 / 冒充检测** | 在 GitHub 上搜索*您*的代码库的恶意逐字副本。 |
| 📊 **账户信任评分** | 为整个账户提供 0–100 的风险等级评分——包括账户年龄、2FA、聚类活动。 |
| 🔔 **持续警报** | 每日的后台扫描会在出现*新*的您作品的克隆时立即通过电子邮件通知您。 |
您还可以**在信任任何代码库或账户之前对其进行审查**——这对于通过搜索或 AI 编程助手(这是此次攻击活动的主要目标)呈现的代码库非常有用。
## 威胁
攻击者在一个一次性账户下逐字克隆一个真实的、受欢迎的代码库——包括完整的提交历史、贡献者列表和 README——(**不是** GitHub fork,因此看起来像原创的)。他们只改变了一件事:README 通过一个 `Update README.md` 提交,添加了一个指向受密码保护的 ZIP 文件的下载链接。
该 ZIP 文件包含一个 LuaJIT 加载器(`loader.exe` / `unit.exe` / `boot.exe` / `lua51.dll` + 一个 `.cmd` 启动器),它会拉取 SmartLoader → StealC。该下载链接在 VirusTotal 上显示为**干净**——只有解压后的 ZIP 文件才会触发杀毒软件。**大约 10,000 个此类代码库未被发现的时间超过一年。** GitHub Healthcheck 编码了研究人员用来发现它们的确切特征。
## 工作原理
启发式方法改编自公开披露的信息以及作者开源的 CLI [`git-malware-finder`](https://github.com/orchidfiles/git-malware-finder)(上游没有 license 文件——参见 [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md))。检测引擎(`src/engine/`)是**纯粹的且经过了完整的单元测试**。它会针对每个代码库检查:
| 信号 | 为什么重要 |
| --- | --- |
| README 引用了二进制文件/归档文件(`.zip`, `.exe`, `.dll`, …) | 武器化克隆唯一添加的有效载荷。 |
| 下载**徽章** (shields.io) → 归档文件 | 真正的文档被替换为指向同一个 ZIP 文件的下载按钮。 |
| **受密码保护**的归档文件描述 | 蓄意逃避 AV / VirusTotal 检测。 |
| URL 缩短器 / 匿名文件托管(`bit.ly`, `mega.nz`, `t.me`…) | 隐藏并轮换有效载荷 URL。 |
| 二进制文件旁边的“免费 / 破解 / 完整版”诱饵 | 社会工程学钩子。 |
| **最新的提交仅更改了 README** | 武器化克隆最明显的单一特征。 |
| 简单的 `Update README.md` 提交信息 | 每个恶意克隆都共享了这个。 |
| 休眠代码,突然更新的 README | 很长一段时间的间隔后,孤立的 README 更改会重新激活克隆。 |
| 许多继承的贡献者,一个最近的 README 编辑者 | 历史记录是从克隆中继承的,而不是自然积累的。 |
| 名为 `loader.exe` / `lua51.dll` / `*.cmd` 的 Release 资产 | 此次攻击活动轮换使用的有效载荷。 |
| 加载器 / 启动器 / `.cso` 提交在代码树中 | 仓库中确切的 ZIP 文件集合。 |
| 深埋在代码树中的归档文件 | 伪装成 release 产物的有效载荷。 |
**账户级别:** 全新的账户、仅自己禁用了 2FA、突然集中创建的代码库、多个推送归档文件的 README、许多几乎没有社交足迹的代码库。检查结果将合并为一个收益递减的 0–100 分数和一个等级:`safe → low → elevated → high → critical`。
## 架构
在 Cloudflare 上实现端到端的 TypeScript——一个集成了身份验证、数据、调度和电子邮件的平台:
```
React + Vite SPA ──> Cloudflare Worker (Hono) ──> GitHub REST / GraphQL
web/ src/ api.github.com
├─ engine/ pure detection rules + scoring (unit-tested)
├─ github/ API client, snapshots, clone detection
├─ auth/ GitHub OAuth, AES-GCM-encrypted sessions
├─ routes/ /api/me · /report · /scan · /clones · /alerts
└─ alerts/ D1 store, email, daily cron re-scan
│
D1 (SQLite) + Cron Trigger (daily) + Email (Cloudflare)
```
- **会话**位于服务器端:GitHub token 在 D1 中使用 AES-GCM 静态加密;浏览器 cookie 仅保存一个不透明的、高熵的 id(`httpOnly`、`Secure`、`SameSite=Lax`)。
- **OAuth** 请求最小权限:公开扫描使用 `read:user`,仅当用户选择加入私有代码库时才使用 `repo`。CSRF `state` 使用 HMAC 签名。
- **警报**存储一个加密的长期 token,以便每日的 Cron Trigger 可以代表用户重新搜索,与已知克隆的基线进行比对,并且仅通过电子邮件发送*新*出现的克隆。
## 快速开始
```
pnpm install
cp .dev.vars.example .dev.vars # then fill in the values below
pnpm db:init # create local D1 tables
pnpm dev # SPA on :5173, Worker API on :8787 (proxied)
```
打开 。
**`.dev.vars`**(已在 gitignore 中)需要:
- `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` —— 来自 GitHub OAuth App([创建一个](https://github.com/settings/developers)):
- Homepage URL:`http://localhost:8787`
- Authorization callback URL:`http://localhost:8787/auth/callback`
- `SESSION_SECRET` —— `openssl rand -hex 32`(也用于静态加密 GitHub token;必须 ≥ 32 个字符)
电子邮件通过 Cloudflare Email Sending 的 `EMAIL` 绑定发送——无需 API 密钥。在开发环境中,Vite (`:5173`) 将 `/api` + `/auth` 代理到 wrangler (`:8787`),因此 OAuth 回调必须指向 `:8787`。
### 脚本
| 脚本 | 作用 |
| --- | --- |
| `pnpm dev` | 同时运行 SPA + Worker |
| `pnpm test` | 检测引擎 + 单元测试 |
| `pnpm test:integration` | Workers-pool + D1 集成测试 |
| `pnpm typecheck` | 对 Worker + SPA 进行类型检查 |
| `pnpm lint` | Biome lint / 格式检查 |
| `pnpm build:web` | 将 SPA 构建到 `web/dist` |
| `pnpm db:init` | 在本地应用 D1 schema |
## 部署
## Fork 与自托管
此代码库连接到了维护者的域名和账户。要运行您自己的实例,请替换以下示例值:
| 项目 | 位置 |
| --- | --- |
| App URL | `wrangler.jsonc` → `vars.APP_URL` |
| OAuth client id | `wrangler.jsonc` → `vars.GITHUB_CLIENT_ID` (生产环境) 和 `.dev.vars` (本地) |
| 自定义域名 | `wrangler.jsonc` → `routes[0].pattern` |
| 电子邮件发件人域名 | `wrangler.jsonc` → `send_email[0].allowed_sender_addresses` |
| 警报发件地址 | `wrangler.jsonc` → `vars.ALERT_FROM_EMAIL` |
| SPA 发件人(收件箱深度链接) | `web/src/mailProvider.ts` `SENDER`,或构建时的 `VITE_ALERT_FROM_EMAIL` |
| 引导管理员登录 | `ADMIN_LOGINS` 环境变量(逗号分隔)——生产环境在 `wrangler.jsonc` `vars` 中,本地在 `.dev.vars` 中 |
| 支持 / 捐赠 URL | `web/src/components/SupportButton.tsx` → `SUPPORT_URL` |
保持 `wrangler.jsonc` 中的 `ALERT_FROM_EMAIL` 与 SPA 的 `SENDER` 一致,以便“打开您的收件箱”深度链接可以根据实际发送邮件的地址进行过滤。
## 安全与隐私
- **纯文本,无 SSRF。** 仅会调用 `api.github.com`;不下载或执行任何归档文件,也不获取任何用户提供的 URL。
- **静态凭证。** GitHub token 使用 AES-GCM 加密;session id 以哈希形式存储。
- **彻底擦除。** **Alerts** 选项卡 → **Delete account**,或 `DELETE /api/me`,将撤销 GitHub 授权并删除所有存储的数据。
- 发现漏洞?请参见 [`SECURITY.md`](SECURITY.md) ——请私下报告。
## 技术栈
**Cloudflare Workers** (Hono) · **D1** (SQLite) · **Cron Triggers** · **Cloudflare Email** · **React 19** + **Vite** · **TypeScript** · **Biome** · **Vitest** (`@cloudflare/vitest-pool-workers`) · **pnpm**
启发式方法是数据驱动的(`src/engine/constants.ts`)——随着攻击活动的演变扩展词汇表,而无需触碰规则逻辑。扫描设有上限(默认每个账户 30 个代码库;对于克隆搜索,取 star 最多的前 10 个,最多 15 个),以保持在 GitHub 的 rate 预算范围内;上限是可配置的。
## License
[MIT](LICENSE) © Josh Tomaino。检测方法改编自带有归属的公开披露信息——请参见 [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md)。
一次性设置
1. **创建 Cloudflare 资源**(一次,由管理员完成): pnpm exec wrangler d1 create github-healthcheck-db # 将 id 粘贴到 wrangler.jsonc → d1_databases[0].database_id 确保父区域(`beardwho.codes`)在同一个 Cloudflare 账户中处于活动状态——自定义域名位于其下,并且 wrangler 会在部署时为其配置 DNS 记录 + TLS 证书。 2. **创建生产环境 GitHub OAuth App**: - Homepage URL:`https://github-healthcheck.beardwho.codes` - Authorization callback URL:`https://github-healthcheck.beardwho.codes/auth/callback` 将其 client id 放入 `wrangler.jsonc` → `vars.GITHUB_CLIENT_ID`。 3. **设置 Worker secrets**(在部署中持久存在——只需设置一次): pnpm exec wrangler secret put GITHUB_CLIENT_SECRET pnpm exec wrangler secret put SESSION_SECRET 4. **添加 Actions secrets**(Settings → Secrets and variables → Actions):`CLOUDFLARE_API_TOKEN`(Workers + D1 + DNS edit),`CLOUDFLARE_ACCOUNT_ID`。 5. **启动开关**:添加代码库**变量** `DEPLOY_ENABLED=true`。部署任务受此限制,因此在您的 Cloudflare 设置准备就绪之前,推送将保持绿色(仅构建 + 测试)。标签:Go语言工具, TypeScript, 克隆仓库检测, 域名收集, 威胁情报, 安全插件, 开发者工具, 程序员工具, 自动化攻击, 配置审计