jasonflaherty/foxhole
GitHub: jasonflaherty/foxhole
一款离线优先的本地及 CI 供应链安全扫描器,集中检测依赖漏洞、密钥泄漏、EOL 运行时与配置风险并支持构建拦截。
Stars: 0 | Forks: 0
# Foxhole
适用于本地项目和 CI 的离线优先供应链扫描器。
Foxhole 会扫描工作区,查找依赖项漏洞、secrets、EOL runtime、高风险
许可证以及 Dockerfile 问题。所有结果都会汇总到**一个 findings 列表**中
(通过 `kind` 进行标记)。随后,你可以进行报告、拦截构建、通知或导出审计
证据——这一切都是确定性的,并支持使用可选的本地漏洞数据库在离线环境下运行。
| | |
|--|--|
| **镜像** | `ghcr.io/jasonflaherty/foxhole`(以及配置后的 Docker Hub) |
| **许可证** | MIT |
| **非此类工具** | 不是 SaaS dashboard、Dependabot 或像 Trivy 这样的镜像扫描器 |
## 快速开始(5 分钟)
从此仓库:
```
git clone https://github.com/jasonflaherty/foxhole.git
cd foxhole
go build -o bin/foxhole ./cmd/foxhole
# 1) 加载演示 vuln 数据(无网络)
./bin/foxhole db update examples/go-demo --offline
# 2) 扫描存在漏洞的 Go fixture
./bin/foxhole examples/go-demo --offline --secrets=false --eol=false
# 3) Secrets + EOL fixture
./bin/foxhole examples/phase2-findings --offline
```
或安装二进制文件 / 拉取镜像:
```
go install github.com/jasonflaherty/foxhole/cmd/foxhole@latest
# 或
docker pull ghcr.io/jasonflaherty/foxhole:v0.4.0
# Docker Hub(如果已发布):docker pull /foxhole:v0.4.0
```
## 核心理念
```
db update → scan path → report / policy / evidence / notify
│
└─ findings[] each with kind: vuln | secret | eol | misconfig | license
```
1. **`foxhole db update`** — 刷新本地 SQLite DB(默认为 `~/.foxhole/foxhole.db`)。使用 `--offline` 加载内置的演示种子数据;要获取真实覆盖范围,请在线更新(或导入 [DB bundle](docs/AIRGAP.md))。
2. **`foxhole `** — 扫描。始终会写入历史记录(`foxhole history`)。
3. **可选参数** — 报告、CI policy、evidence pack、triage、通知。
**退出代码**
| 代码 | 含义 |
|------|---------|
| `0` | OK(或未配置 policy) |
| `1` | 工具 / 使用错误,或 **数据库过期**(`--max-db-age`) |
| `2` | Policy gate 失败(`--fail-on` / `--policy`) |
检测结果始终是确定性的。`--triage-ai` / `--remediate-ai` 仅生成文本草稿;它们绝不会改变通过或失败的结果。
## 检测结果
| `kind` | 含义 |
|--------|---------|
| `vuln` | 依赖项公告(NVD / OSV / GHSA) |
| `secret` | 凭证模式(精选的 AWS/GCP/Azure/GitHub/JWT/PEM/… 规则) |
| `eol` | 生命周期结束(EOL)的 runtime |
| `misconfig` | Dockerfile 加固 |
| `license` | 高风险许可证信号 |
```
[HIGH] CVE-2024-… (vuln)
package: github.com/vulnerable/lib@v1.0.0 (Go)
[CRITICAL] aws-access-key (secret)
path: demo.env:4
```
## 日常使用
### 扫描并报告
```
foxhole . # console
foxhole . --report console,json,sarif,html # files in cwd
foxhole . --report console,junit,cyclonedx,spdx # CI / SBOM
foxhole . --secrets=false --eol=false # turn scanners off
```
### 拦截构建(policy)
```
foxhole . --fail-on high
foxhole . --policy examples/policy.yaml
foxhole . --policy-dir examples/policy-pack # merge org YAML packs
foxhole policy validate examples/policy-pack # fingerprint + expired suppressions
```
Policy YAML 支持 `fail_on`、`kinds`、永久 `ignore` 以及有期限的
`suppressions`(`until` / `ticket` / `reason`)。请参阅 [examples/policy.yaml](examples/policy.yaml)。
### 审计 evidence
```
foxhole . --policy examples/policy.yaml --evidence --split-reports --max-db-age 720h
```
生成 `foxhole-evidence/`(包含数据库哈希 + policy 指纹的清单、SARIF、
suppressions)以及按 `kind` 划分的 JSON(`foxhole-secrets.json` 等)。
### Triage(负责解释,不参与检测)
```
foxhole . --triage # foxhole-triage.md + .json (deterministic)
foxhole . --triage --triage-ai # optional LLM prose; needs FOXHOLE_AI_API_KEY
```
### 基于差异(Diff-driven)的 GitHub issues
```
export FOXHOLE_GITHUB_TOKEN=… FOXHOLE_GITHUB_REPO=owner/repo
foxhole . --github-diff --triage # one issue per NEW finding vs last green; close when fixed
foxhole . --github # legacy: one summary issue with everything
```
### 历史与归档
```
foxhole . --archive
foxhole history
foxhole diff last .
```
## CI 方案
**最小化 gate**
```
foxhole db update
foxhole . --fail-on high --report console,sarif
```
**合规 / Jenkins 风格**
```
foxhole db update # or: foxhole db import ./foxhole-db.tar.gz
foxhole . --offline --max-db-age 720h \
--policy-dir ./policy-pack \
--evidence --split-reports \
--report console,json,sarif,html
```
复制粘贴 Jenkins + 共享库:[examples/jenkins/](examples/jenkins/)。
Air-gap(已签名镜像 + DB bundle):[docs/AIRGAP.md](docs/AIRGAP.md)。
Actions 中的功能演示:[examples/README.md](examples/README.md)。
**GitHub Actions (Check Run)**
```
- run: foxhole . --offline --github-checks --fail-on high
env:
FOXHOLE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FOXHOLE_GITHUB_REPO: ${{ github.repository }}
FOXHOLE_GIT_SHA: ${{ github.sha }}
```
## 通知
设置环境变量 → 传入对应的参数。如果不传参数,则不会发送任何内容。通知
失败会被记录在日志中;它们**不会**改变退出代码。
| 参数 | 环境变量 |
|------|-----|
| `--slack` | `FOXHOLE_SLACK_WEBHOOK` |
| `--teams` | `FOXHOLE_TEAMS_WEBHOOK` |
| `--discord` | `FOXHOLE_DISCORD_WEBHOOK` |
| `--webhook` | `FOXHOLE_WEBHOOK_URL` |
| `--email` | `FOXHOLE_SMTP_*`, `FOXHOLE_EMAIL_FROM`, `FOXHOLE_EMAIL_TO` |
| `--github` / `--github-diff` | `FOXHOLE_GITHUB_TOKEN`, `FOXHOLE_GITHUB_REPO` |
| `--github-checks` | 同上 + `FOXHOLE_GIT_SHA` |
```
export FOXHOLE_SLACK_WEBHOOK='https://hooks.slack.com/services/…'
foxhole . --slack
```
容器提示:将相同的环境变量传入 `docker run -e FOXHOLE_SLACK_WEBHOOK …`。
## 数据库命令
```
foxhole db update [path] # refresh providers (online or --offline seeds)
foxhole db verify # integrity + last sync age
foxhole db export -o bundle.tar.gz # air-gap bundle
foxhole db import bundle.tar.gz # install bundle into --db-path
```
## REST API(`foxhole serve`)
仅适用于受信任的网络。设置了 `FOXHOLE_API_TOKEN` 后,`/scan`、`/db/update`
和 `/history` 将要求提供 `Authorization: Bearer `(或 `X-Foxhole-Token`)。
`/health`、`/version` 和 `/` 仍保持公开。
```
export FOXHOLE_API_TOKEN='…' # optional
foxhole serve --addr :8080
```
## Docker / Podman
```
docker run --rm \
-v foxhole-data:/var/lib/foxhole \
-v "$PWD:/work:ro" \
ghcr.io/jasonflaherty/foxhole:v0.4.0 /work --offline
./docker/run-demo.sh # offline go-demo in one shot
```
更多挂载和 cosign 验证:[docker/README.md](docker/README.md)。
## 配置
优先级:**参数 > `FOXHOLE_*` 环境变量 > `foxhole.yaml`**
| 设置 | 参数 / 环境变量 | 默认值 |
|---------|------------|---------|
| SQLite DB | `--db-path` / `FOXHOLE_DB_PATH` | `~/.foxhole/foxhole.db` |
| 离线模式 | `--offline` / `FOXHOLE_OFFLINE` | `false` |
| 报告 | `--report` / `FOXHOLE_REPORT` | `console` |
| NVD API key | `--nvd-api-key` / `FOXHOLE_NVD_API_KEY` | 空 |
| Policy 文件 | `--policy` / `FOXHOLE_POLICY` | 空 |
| Policy pack | `--policy-dir` / `FOXHOLE_POLICY_DIR` | 空 |
| Fail-on | `--fail-on` / `FOXHOLE_FAIL_ON` | 空 |
| 数据库最大有效期 | `--max-db-age` / `FOXHOLE_MAX_DB_AGE` | 空 (关闭) |
| Evidence | `--evidence` / `FOXHOLE_EVIDENCE` | `false` |
| Triage | `--triage` / `--triage-ai` | `false` |
| Serve token | `FOXHOLE_API_TOKEN` | 空 (关闭认证) |
示例文件:[examples/foxhole.yaml](examples/foxhole.yaml)。
## 文档导图
| 文档 | 何时阅读 |
|-----|-----------------|
| [examples/README.md](examples/README.md) | 测试夹具 + 指导运行哪些 Actions 演示 |
| [examples/jenkins/](examples/jenkins/) | Jenkins pipeline / 共享库 |
| [docs/AIRGAP.md](docs/AIRGAP.md) | 离线 / 物理隔离 CI |
| [docker/README.md](docker/README.md) | 镜像、数据卷、cosign |
| [docs/ROADMAP.md](docs/ROADMAP.md) | 已发布的功能 |
| [docs/Foxhole_Design_Book.md](docs/Foxhole_Design_Book.md) | 架构 |
## 开发
```
go test ./...
golangci-lint run
go build -o bin/foxhole ./cmd/foxhole
```
## 致谢
Foxhole 依托于公开的安全数据和社区的 pattern 探索工作。我们**不会**
直接整体照搬这些项目;而是将它们作为事实来源或灵感启发。
| 来源 | Foxhole 如何使用 |
|--------|---------------------|
| [NVD](https://nvd.nist.gov/) | 通过 NVD API 获取 CVE 公告(`db update`) |
| [OSV](https://osv.dev/) | 生态系统公告(`db update`) |
| [GitHub Advisory Database (GHSA)](https://github.com/advisories) | 本地公告存储中的 GHSA 记录 |
| [CISA KEV](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) / [EPSS](https://www.first.org/epss/) | 可选的数据富集(`--enrich`) |
| [endoflife.date](https://endoflife.date/) | 从种子 runtime 检查中关联的 EOL 生命周期日期 |
| [secrets-patterns-db](https://github.com/mazen160/secrets-patterns-db) | 为精选的 secret 规则包(`internal/seeds/secrets.json`)提供灵感 — 仅包含高可信度的 AWS/GCP/Azure/GitHub/JWT/PEM 风格的 pattern;并未完整导入该 YAML/TOML DB |
与 [TruffleHog](https://github.com/trufflesecurity/trufflehog) 或
[Gitleaks](https://github.com/gitleaks/gitleaks) 等专用扫描器相比,我们的 secret 检测在覆盖面上被有意保持在较窄的范围。
请参阅 [`.github/workflows/compare-juice-shop.yml`](.github/workflows/compare-juice-shop.yml) 了解在 Juice Shop 上的对比结果。
## 许可证
MIT — 请参阅 [LICENSE](LICENSE)。
标签:DevSecOps, EVTX分析, Go, Ruby工具, 上游代理, 开源框架, 持续集成, 日志审计, 请求拦截, 错误基检测, 静态代码分析