RefuseHQ/refuse

GitHub: RefuseHQ/refuse

refuse 是一个可自托管的 HTTP 服务,通过聚合多个公开漏洞数据库,为 CLI shim 和 CI 流水线提供包级别的安装前漏洞拦截与安全版本建议。

Stars: 5 | Forks: 4

# refuse **为 [`refuse-cli`](https://github.com/RefuseHQ/refuse-cli) 提供支持的可自托管后端,用于阻止安装存在漏洞的包。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/17c81586c6235108.svg)](https://github.com/RefuseHQ/refuse/actions/workflows/ci.yaml) [![CodeQL](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/d269e7e789235114.svg)](https://github.com/RefuseHQ/refuse/actions/workflows/codeql.yml) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![Container](https://img.shields.io/badge/ghcr.io%2Frefusehq%2Frefuse-latest-1f6feb?logo=docker)](https://github.com/RefuseHQ/refuse/pkgs/container/refuse) [![Release](https://img.shields.io/github/v/release/RefuseHQ/refuse?display_name=tag&sort=semver&cacheSeconds=3600)](https://github.com/RefuseHQ/refuse/releases)
一个小型 HTTP 服务,接收公共漏洞 + 元数据源 —— [OSV](https://osv.dev/)、[deps.dev](https://deps.dev/)、[CISA KEV](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)、[FIRST EPSS](https://www.first.org/epss/)、[GitHub Security Advisories](https://github.com/advisories)、[Wolfi](https://github.com/wolfi-dev/advisories) —— 存入本地 SQLite 数据库,并回答如下问题: - *`lodash@4.17.10` 有漏洞吗?* - *`requests` 的最低安全升级版本是什么?* - *这个 `package-lock.json` 中的 250 个包里是否有已知的恶意包?* - *这个 Dockerfile 是否安装了包含 CVE 的 apt 包?* 预期调用方是 [`refuse-cli`](https://github.com/RefuseHQ/refuse-cli) —— 一个小巧的 shim,包装了 `npm`、`pnpm`、`yarn`、`pip`、`cargo`、`gem`、`bun`、`go`,并拒绝为已知的恶意包运行安装。该服务器也是标准的 REST API,因此 `curl`、CI 步骤或任何其他客户端都可以使用它。 ## 运行位置 一个长期运行的 HTTP 服务 —— 选择一台主机: - **笔记本电脑** —— `docker run`,绑定到 localhost。匿名模式即可。 - **团队 VM** —— 同一镜像位于你的反向代理之后,通过 API key 锁定。 - **托管** —— [refuse.dev](https://refuse.dev) 为你运行相同的镜像。 CLI 端集成(PATH shim、pre-commit、GitHub Actions、Docker 构建)位于 [`refuse-cli`](https://github.com/RefuseHQ/refuse-cli) 中。 ## 功能说明 - **REST API** —— `POST /api/v1/check/{package, batch, lockfile, dockerfile, workflow}` 和 `suggest-safe-version`。JSON 输入/输出,可选 bearer 认证。 - **数据摄入** 在进程内运行:OSV 约每 5 分钟一次,deps.dev 约每 15 分钟一次,每日执行 KEV / EPSS / GHSA / Wolfi 丰富化。所有源均为公开,运行时不会向除此之外发起调用。 - **内嵌式 SQLite**(WAL 模式),一个容器,一个卷。 - 位于 `/ui/` 的 **管理界面** 用于查看数据源健康状况、手动触发摄入以及 API key 的 CRUD。 ## 快速开始 ### 1. 启动带有持久化卷的服务器 ``` docker run -d --name refuse -p 8080:8080 \ -v refuse-data:/data \ ghcr.io/refusehq/refuse:latest ``` ### 2. 观察冷启动数据播种(约 3 分钟) ``` docker logs -f refuse ``` 首次启动会流式传输 OSV 的批量存档(一次遍历所有生态系统 —— npm、PyPI、Maven、Go、crates.io、RubyGems ……以及 OSV 团队发布的每一个 Debian / Ubuntu / Alpine / RHEL 发行版),同时并行处理 KEV、EPSS、GHSA 和 Wolfi。进度条展示了当前状态: ``` refuse: ingest[osv:bulk ] [██████████░░░░░░░░░░] 50% • 75000 records • 1m30s refuse: ingest[kev ] [████████████████████] 100% • 1542/1542 entries refuse: ingest[epss ] [████████████████████] 87% • 245678 rows scored refuse: ingest[ghsa ] ✓ done — 100 records in 2s (cursor saved) refuse: ingest[wolfi ] ✓ done — 1247 records across 412 packages in 4s ``` 在此一次性引导之后,每 5 分钟的增量更新只需几秒钟。 ### 3. 等待 `/readyz` ``` curl http://localhost:8080/readyz ``` 在数据源进行引导时返回带有 `pending_sources` 列表的 `503` 状态码,并在每个必需的数据源至少完成一次遍历后返回 `200`: ``` { "ready": true, "ready_sources": ["osv", "kev", "epss", "ghsa_direct", "wolfi"], "pending_sources": [], "osv_ecosystems_done": 26, "osv_ecosystems_total": 26 } ``` ### 4. 将 [`refuse-cli`](https://github.com/RefuseHQ/refuse-cli) 指向它 ``` refuse config set server_url http://localhost:8080 refuse install # drop PATH shims into ~/.refuse/bin npm install lodash@4.17.10 # refuse: blocked — CVE-2019-10744 (critical); 建议 4.17.21 ``` 也支持直接的 REST 调用 —— 适用于不希望使用该 shim 的任何客户端: ``` curl -sX POST http://localhost:8080/api/v1/check/package \ -H 'Content-Type: application/json' \ -d '{"ecosystem":"npm","name":"lodash","version":"4.17.10"}' | jq . ``` 或者浏览 查看仪表板。 ## 生产环境部署 (compose) ``` services: refuse: image: ghcr.io/refusehq/refuse:latest ports: ["8080:8080"] volumes: ["./data:/data"] restart: unless-stopped environment: REFUSE_REQUIRE_KEY: "true" REFUSE_ADMIN_TOKEN: "${REFUSE_ADMIN_TOKEN:?set it before starting}" # REFUSE_GITHUB_TOKEN: ghp_... (optional, raises GHSA ingest rate limit) healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/healthz').then(r=>process.exit(r.ok?0:1))"] interval: 30s retries: 3 ``` 请查看 [`docker/docker-compose.with-key.yml`](docker/docker-compose.with-key.yml) 获取带有注释的相同配置。 ## 配置说明 一切均由环境变量驱动。默认值选择了安全的配置,因此无需任何标志即可运行 `docker run`。 | 变量 | 默认值 | 用途 | | --- | --- | --- | | `REFUSE_PORT` | `8080` | HTTP 监听端口 | | `REFUSE_DB_PATH` | `/data/refuse.db` | SQLite 文件路径 | | `REFUSE_REQUIRE_KEY` | `false` | 在 `/api/v1/check/*` 上要求 `Authorization: Bearer rfs_…` | | `REFUSE_ADMIN_TOKEN` | *(未设置)* | 用于管理界面 + key CRUD 的静态 bearer | | `REFUSE_OSV_FREQUENCY` | `5` | OSV 增量运行间隔(分钟) | | `REFUSE_DEVS_DEV_FREQUENCY` | `15` | deps.dev 运行间隔(分钟) | | `REFUSE_ENRICHMENT_CRON` | `0 5 * * *` | 用于 KEV/EPSS/GHSA/Wolfi 的 Cron 表达式 | | `REFUSE_BOOTSTRAP_ON_EMPTY` | `true` | 如果数据库为空,首次启动时同步拉取 OSV | | `REFUSE_DISABLE_INGEST` | `false` | 只读镜像模式(用于预播种快照) | | `REFUSE_GITHUB_TOKEN` | *(未设置)* | 可选的 GH token,可提高 GHSA-direct 的速率限制 | | `REFUSE_CARD_CACHE_SIZE` | `5000` | 构建的 `VulnCard`s 的 LRU 条目数 | | `REFUSE_CARD_CACHE_TTL_SECONDS` | `600` | 该 LRU 的 TTL | | `REFUSE_LOG_LEVEL` | `info` | `debug` / `info` / `warn` / `error` | | `REFUSE_CORS_ORIGIN` | `*` | `/api/v1/check/*` 上的 CORS allow-origin | 完整参考:[`docs/configuration.md`](docs/configuration.md)。 ## API 概览 | | | | --- | --- | | `GET /healthz` | 存活探针 | | `POST /api/v1/check/package` | 单包漏洞检查 | | `POST /api/v1/check/batch` | 并行检查多个包 | | `POST /api/v1/check/lockfile` | 解析并扫描整个 lockfile | | `POST /api/v1/check/dockerfile` | 解析并扫描基础镜像 + RUN 行 | | `POST /api/v1/check/workflow` | 扫描 GitHub Actions 的 `uses:` 条目 | | `POST /api/v1/suggest-safe-version` | 为受影响的包提供最低安全升级版本 | | `GET /api/admin/stats` | 数据库行数统计(管理员 token) | | `GET /api/admin/sources` | 每个摄入源的最后一次运行 / 上次成功记录 | | `POST /api/admin/ingest/{osv,deps-dev,enrichment}` | 手动触发 | | `GET/POST/DELETE /api/keys[/:id]` | API key 的 CRUD | | `GET /ui/` | 面向自托管运维人员的管理仪表板 | 完整 schema 参考:[`docs/api.md`](docs/api.md)。 ## refuse 家族 | | 它是什么 | 何时使用 | | --- | --- | --- | | **[refuse](https://github.com/RefuseHQ/refuse)**(本仓库) | 可自托管的 HTTP 服务器 | 当你想要自己的后端时 —— 无论是因为气隙隔离、本地部署还是其他原因 | | **[refuse-cli](https://github.com/RefuseHQ/refuse-cli)** | 包装了 `npm` / `pip` / `cargo` / ... 的 PATH shim | 当你想在开发机器或 CI 上在安装发生之前阻止它们时 | 两者共享解析器、版本比较器和基于 OSV 派生的数据模型。 ## 对比 | | refuse | OSV-scanner | Trivy / Grype | Dependency-Track | guarddog | npq | | --- | --- | --- | --- | --- | --- | --- | | 开源协议 | Apache-2.0 | Apache-2.0 | Apache-2.0 | Apache-2.0 | Apache-2.0 | MIT | | 独立服务器 | ✅ | — | 部分 | ✅ | — | — | | **通过 PATH shim 进行安装时拦截**(配合 [`refuse-cli`](https://github.com/RefuseHQ/refuse-cli)) | ✅ | — | — | — | — | ✅ | | **Dockerfile 解析(基础镜像 + RUN)** | ✅ | — | ✅(机制不同) | — | — | — | | OSV 数据 | ✅ | ✅ | ✅ | ✅ | — | — | | KEV / EPSS 丰富化 | ✅ | — | 部分 | ✅ | — | — | | GitHub Actions `uses:` 扫描 | ✅ | — | 部分 | — | — | — | | 启发式恶意包检测 | 部分 | — | — | — | ✅ | 部分 | | 单容器部署 | ✅ | n/a | ✅ | ✅ | n/a | n/a | `refuse` 的核心差异在于 **安装时拦截** —— 在运行前拒绝安装,而不是事后报告依赖树的状态。CLI shim 使这种拦截对开发者或 CI 步骤是透明的。如果你已经在运行 Trivy 或 Dependency-Track 进行安装后监控,refuse 可以与它们互补:结构化的拒绝记录(包、版本、原因、OSV id)可以无缝接入任一 pipeline。 ## 自托管指南 ### 单个开发者(笔记本电脑) ``` mkdir -p ~/refuse-data docker run -d --name refuse \ -p 8080:8080 -v ~/refuse-data:/data \ --restart unless-stopped \ ghcr.io/refusehq/refuse:latest # 安装 CLI (从 refuse-cli repo) brew install refusehq/tap/refuse refuse config set server_url http://localhost:8080 refuse install ``` 在此场景下使用匿名模式即可 —— 服务器仅绑定到 `localhost`。 ### 团队集群(真实域名,持久化卷) 位于带有 TLS 的 nginx/Caddy 之后: ``` services: refuse: image: ghcr.io/refusehq/refuse:latest volumes: ["/srv/refuse:/data"] environment: REFUSE_REQUIRE_KEY: "true" REFUSE_ADMIN_TOKEN: "${REFUSE_ADMIN_TOKEN}" REFUSE_GITHUB_TOKEN: "${REFUSE_GITHUB_TOKEN}" REFUSE_CORS_ORIGIN: "https://your-app.example.com" restart: unless-stopped ``` 将 DNS 记录指向该主机,在你的反向代理中终结 TLS,并定期轮换 `REFUSE_ADMIN_TOKEN`。通过 cron `cp` 备份 `/srv/refuse/refuse.db` —— SQLite WAL 使热拷贝安全可行。 详细指南:[`docs/self-hosting.md`](docs/self-hosting.md)。 ## 从源码构建 ``` git clone https://github.com/RefuseHQ/refuse.git cd refuse pnpm install pnpm typecheck && pnpm test pnpm --filter @refuse-oss/server dev # hot reload on src/ # 本地构建 Docker 镜像 make docker make docker-run # → http://localhost:8080 ``` 仓库结构: ``` apps/server/ # Hono server, REST API, tools, ingest, UI src/ config.ts # env validation db/ # SQLite client + D1-shape facade + migrations http/ # router, REST, auth, admin tools/ # the six check_* tools ingest/ # cron scheduler + OSV/deps.dev/KEV/EPSS/GHSA/Wolfi cards/ # VulnCard reader (LRU on top of SQLite) ui/static/ # tiny vanilla SPA packages/ shared/ # zod schemas, ecosystem normalization versions/ # version matchers (semver, pypi, maven, dpkg, …) docker/ # Dockerfile + compose examples + entrypoint ``` 请查看 [ARCHITECTURE.md](./ARCHITECTURE.md) 了解更深入的说明。 ## 安全性 安全策略:[SECURITY.md](./SECURITY.md)。请通过 [hello@refuse.dev](mailto:hello@refuse.dev) 或 [GitHub 私密漏洞报告](https://github.com/RefuseHQ/refuse/security/advisories/new) 私下报告。 ## 致谢 基于 [OSV.dev](https://osv.dev/)、[deps.dev](https://deps.dev/)、[CISA KEV 目录](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)、[FIRST EPSS](https://www.first.org/epss/)、[GitHub Security Advisories](https://github.com/advisories) 和 [Wolfi advisories](https://github.com/wolfi-dev/advisories) 构建。 ## 许可证 [Apache License 2.0](./LICENSE) © RefuseHQ.
标签:GPT, MITM代理, REST API, 后端服务, 安全防护, 漏洞管理, 网络测绘, 脚本检测, 自动化攻击, 请求拦截