Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
safer-dependencies — 自动化依赖安全层,专为AI编码助手设计,可审计npm、PyPI、RubyGems、Maven、Go及Rust生态系统中的包,检测CVE、打字劫持、废弃、版本年龄问题及哈希完整性。 | Kitploit
工具/GitHubGitHub/robert-auger/safer-dependencies
漏洞扫描器DevSecOps秘密检测供应链安全
GitHubrobert-auger/safer-dependencies

safer-dependencies

自动化依赖安全层,专为AI编码助手设计,可审计npm、PyPI、RubyGems、Maven、Go及Rust生态系统中的包,检测CVE、打字劫持、废弃、版本年龄问题及哈希完整性。

查看仓库
302天前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

面向 Claude Code 的 Safer Dependencies

当 Claude 等 AI 编码助手向你的项目添加包时,它们往往会选择一个听起来合理的版本——而不会检查该版本是否存在已知安全漏洞、该包是否仍在积极维护,或者它的名字是否与某个恶意仿冒包仅一字之差。

safer-dependencies 是 Claude Code 的安全层:它位于 Claude 与你的清单文件之间,自动运行安全检查:存在漏洞的安装会在执行前被拒绝,而写入清单的危险版本会在写入后立即在磁盘上被纠正。它能检测并修复有风险的依赖——CVE、typosquat(拼写仿冒包)、废弃包和版本过旧问题,以及对全新发布版本的冷却期——覆盖 npm、PyPI、RubyGems、Maven、Go、Rust 和 PHP(Composer)。确切的覆盖范围请参阅 CAPABILITIES.md。

新来的? GETTING-STARTED.md 可在约五分钟内带你从零到完成可用安装。

安全与隐私: 参见 SECURITY.md(漏洞披露)、PRIVACY.md(数据外发,无遥测)以及 CAPABILITIES.md(工具能防御什么、不能防御什么)。

许可证(源代码可用——并非 OSI“开源”): 可免费用于自身目的的使用和修改,包括营利/公司内部使用以及构建你销售的产品。仅当你想对软件本身进行商业化时——出售、将其嵌入所销售的产品或服务中,或向第三方有偿提供其功能(包括托管/SaaS/API)——才需要单独的付费许可证。再分发和衍生作品必须保留许可证并注明本项目。参见 LICENSE(商业限制见第 4 节);商业许可请求请联系 github.com/robert-auger。

目录

  • 入门 — 约五分钟完成安装
  • 它能做什么
  • 工作原理
    • 普通模式(手动)
    • 拦截模式(自动)
    • 预安装模式(Bash 钩子)
    • 后安装模式(Bash 钩子)
    • 代理后模式(代理钩子对)
  • 触发条件
  • 本仓库包含什么
  • 支持的生态系统
  • 安装
    • 配置
  • 警告级别
  • 审计日志
  • 要求
  • 常见问题

入门

GETTING-STARTED.md 可在约五分钟内带你从零到完成可用安装——包括前置条件、交互式安装和验证。完整的安装参考(全局/项目/手动安装、Windows 特定事项、权限白名单、更新和卸载),请参阅 INSTALLATION.md。

日常使用: 钩子安装后,无需运行任何命令——safer-dependencies 会在后台自动工作。当 Claude 添加或安装包时,它会标记有风险的依赖,并将存在漏洞的版本就地升级为安全版本——甚至会在已知存在漏洞的安装运行之前就将其阻止——因此不安全的包会被捕获并纠正,无需你主动要求。你仍然可以随时直接调用它:"[email protected] 安全吗?"、"检查 safer-dependencies 配置" 或 "显示 safer-dependencies 统计信息"。

它能做什么

当 Claude 即将向你的项目添加包时,safer-dependencies 会拦截并执行 5 项检查:

  1. 来源(Provenance) —— 官方注册表、typosquat(拼写仿冒包)检测(npm/PyPI/RubyGems/Maven/crates.io)、包龄
  2. 版本年龄 —— 选择 7 天前发布的最新稳定版本(冷却期窗口)
  3. 漏洞扫描 —— OSV API,并在可用时使用生态系统原生工具(npm audit、pip-audit、bundle audit)
  4. 哈希固定完整性 —— 对于带有 --hash=sha256:... 固定的 PyPI requirements.txt 行,将声明的哈希与 PyPI 发布的哈希进行校验;不匹配时发出 WARNING
  5. 废弃与陈旧包 —— 已知已废弃的包(例如 paperclip、request、pycrypto、github.com/dgrijalva/jwt-go)会被立即硬阻止,并提供建议的替代包;超过 2 年没有稳定发布的包会得到咨询性 STALE: 警告。被硬阻止的包会从清单中移除,Claude 将询问如何处理;仅被标记为陈旧的包会保留在原处。

如发现问题,Claude 会发出警告,并可能回退到更安全的版本。所有检查都会记录到 ~/.claude/safer-dependencies-audit-YYYY-MM.log(每个自然月一个文件)。

工作原理

该技能以五种模式运行(下面概括;最深入的设计原理见 skills/safer-dependencies.md):

普通模式(手动)

当 Claude 即将写入 import、向清单添加包或更新锁文件时,该技能会在你的会话中内联运行:

  1. 向包注册表查询稳定版本
  2. 自动选择 7 天前发布的最新版本(确定性选择——不依赖 LLM 判断)
  3. 通过生态系统工具和 OSV API 检查已知漏洞
  4. 在可用时验证包签名
  5. 如发现问题则发出警告,并固定精确版本
  6. 将结果记录到审计追踪中

版本选择由随技能捆绑的独立 Python 脚本处理,而非由 LLM 解释规则。该命令输出 SELECTED: <version>,Claude 会原样使用该版本。

拦截模式(自动)

使用 PostToolUse 钩子配置 .claude/settings.json,以启用自动、透明的包验证:

  1. Claude 将最初请求的版本写入清单文件(例如 package.json)——文件落到磁盘上
  2. PostToolUse 钩子在写入完成后立即触发,并调用 safer-dependencies-shim.sh
  3. shim 读取文件,解析声明的包,并运行所有安全检查(typosquat、废弃、CVE、陈旧、哈希固定)
  4. 如果需要修正,shim 会就地重写清单为安全版本(或移除没有安全版本的条目)
  5. shim 通过 stdout 上的 hookSpecificOutput.additionalContext 发出信号(UPDATED:、BLOCKED:、WARNING:、STALE:、MAJOR-UPDATE-CONFIRM:、REFACTOR-REQUIRED:、REGRESSION:、TYPOSQUAT-CONFIRM:、VERIFY:、CLEAN:)。当审计日志显示同一个(文件、包)之前曾被修正到相同的安全目标时, 会在 之前出现——也就是说,子代理或过时的计划重新引入了已知存在漏洞的版本,编排者应恢复先前已批准的版本,而不是重新决定主版本升级。

设计说明——Shape C(写入后纠正): 该钩子不会阻止写入。每个存在漏洞的版本都会先落到磁盘上,然后在同一个工具使用周期内被自动纠正。这是相对于 PreToolUse 阻止型设计的一个有意选择——相关权衡请参阅 FAQ.md。

信号示例:``` UPDATED: aiohttp 3.8.5 → 3.9.0 (HIGH: 33 CVEs fixed)

root@kitploit:~
父代理利用这些信号来识别受影响的代码,并按需进行重构。

### 预安装模式(Bash 钩子)

在 `.claude/settings.json` 中配置 `PreToolUse:Bash` 钩子,即可启用对
包管理器安装命令的预检审计。这是对拦截模式的补充(而非替代)——
二者共同构成分层防御。

1. Claude 尝试进行 Bash 工具调用(例如 `npm install [email protected]`)
2. `PreToolUse` 钩子在调用运行之前触发,并调用
   `safer-dependencies-pretooluse-bash.sh`
3. 纯 bash 早期过滤器会在约 115 ms 内短路非包管理器命令
   (不调用 Python),因此 `git status` / `ls` / `npm test` 在热路径上的
   开销可忽略不计
4. 对于可识别的包管理器安装命令(`npm`/`pnpm`/`yarn`
   `install`/`i`/`add`),辅助脚本通过 `shlex` 分词,提取每个
   `pkg@version` 参数,并 POST 到 OSV
5. 任何存在漏洞的具体固定版本 → 钩子返回
   `permissionDecision: "deny"`,并附上每条发现对应的 GHSA-id + CVSS +
   摘要,以及调用 safer-dependencies 技能的提示
6. 安装永远不会执行——不进行网络拉取,也不运行 postinstall 脚本

**为什么在拦截模式之外还需要它:** 写入后 shim 无法感知 Bash。
`npm install [email protected]` 会在任何审计触发之前完整运行(postinstall
脚本同样会执行);`npm install -g typosquat-pkg` 则根本不会写入任何
项目清单。预安装模式从结构上弥补了这些缺口。

预安装模式只能看到用户**输入**的内容(命令行上的 `pkg@version` 参数)。
它无法看到解析器实际将要安装的传递依赖树。**安装后模式**(见下文)会在
安装完成后审计锁文件——这两种模式互为补充,而非冗余。

**范围:** 此处涵盖的包管理器 CLI 横跨五个生态系统
(npm/pnpm/yarn/bun/npx/deno、pip/pip3/pipx/pipenv/uv/uvx/poetry、
gem/bundle、go、cargo),外加通过拦截模式覆盖的 Maven(Maven 依赖通常
声明在 `pom.xml`/`build.gradle` 中,而不是通过 CLI 动词添加)。

> **已知缺口:** Maven CLI 确实支持通过
> `mvn dependency:get -Dartifact=group:art:version` 和 `mvn dependency:copy`
> 直接下载。此钩子尚无法识别这些调用。如果您经常使用它们,现有的
> 写入后 shim 仍然会捕获最终落入清单中的任何内容,但预取保护仅适用于
> 上述列出的生态系统。已作为后续事项跟进。

各生态系统可识别的语法:

| 包管理器 | 动词 | 具体固定版本语法 |
|---|---|---|
| `npm`, `pnpm`, `yarn`, `bun` | `install`, `i`, `add`(外加 `yarn`/`pnpm dlx`、`bun x`、`yarn create`) | `[email protected]`, `@scope/[email protected]` |
| `npx` | (无动词——包为第一个位置参数) | `[email protected]` |
| `deno` | `add`, `install` | `npm:[email protected]`(npm 前缀规范) |
| `pip`, `pip3`, `pipx`, `pipenv`, `uv`, `uvx`, `poetry` | `install`(pip/pip3/pipx/pipenv)/ `add`(uv/poetry)/ 无动词(uvx) | `pkg==1.2.3`(额外项 `pkg[extra]==X` 也已处理) |
| `gem`, `bundle` | `install`(gem)/ `add` | `-v 1.2.3`, `--version 1.2.3`, `--version=1.2.3`(独立标志) |
| `go` | `get`, `install` | `[email protected]`(根据 Go modules 必须包含 `v` 前缀) |
| `cargo` | `add`, `install` | `[email protected]` |

范围固定版本(npm 的 `^4.17`、pip 的 `>=`、poetry 的 `^`/`~`、Go 的
`@latest`)以及未指定版本,都会在安装后交由拦截模式处理——写入后 shim
会审计解析器实际选择的任何版本。自动重写为安全版本已作为后续事项列入计划。

**失败模式:** 失败开放(fail-open)。任何错误(缺少 Python、网络抖动、
输入格式错误)都会以退出码 0 退出且不输出任何内容,从而允许 bash 继续
执行。拦截模式在安装后仍会运行,因此预检失败会优雅地降级至现有的保护机制。

**拒绝示例:**```
safer-dependencies pre-flight audit blocked this install.
Vulnerable pinned version(s) detected:
  - [email protected] → GHSA-35jh-r3h4-6jhm (CVSS:7.4): Command Injection in lodash
Re-run with a patched version, or invoke the safer-dependencies skill
for a recommended pin.

Post-Install 模式(Bash 钩子)

配置 .claude/settings.json,加入一个 PostToolUse:Bash 钩子,以在 Bash 命令执行后启用事后审计。它会针对命令的 cwd 运行三个独立的扫描,每个扫描都弥补了其他钩子无法覆盖的空白:

  • 扫描 A — 锁文件。 在成功的安装动词(npm install、bundle install、poetry install、uv sync、go mod tidy 等)之后,审计新修改的锁文件(package-lock.json、Gemfile.lock、poetry.lock、uv.lock、go.sum、yarn.lock、pnpm-lock.yaml、Pipfile.lock)。这弥补了 传递 CVE 缺口——Pre-Install 无法看到该缺口:用户输入了 pkg@version,但解析器可能拉取了数十个用户未指定的传递依赖。
  • 扫描 B — 清单文件。 在任何不在只读拒绝列表(、、 等)中的 Bash 命令之后,审计新修改的清单文件。这是针对通过 、 或脚本进行的清单编辑的回退方案——这些编辑绕过了 Intercept 模式所挂钩的 / 工具。

扫描如何运行:

  1. Claude 运行一次 Bash 工具调用
  2. PostToolUse 钩子在命令完成之后触发,并调用 safer-dependencies-posttooluse-bash.sh
  3. 一个纯 bash 的早期过滤器会在约 115 ms 内短路掉不匹配任何扫描门的命令(与 Pre-Install 相同的快速路径约定),因此 ls / git / cat 的额外开销可以忽略不计
  4. 每个扫描使用 find -maxdepth 5 遍历 cwd(覆盖 monorepo 布局;排除 node_modules、.git、.venv、venv),查找最近 60 秒内被修改的文件——可通过 SAFE_DEP_POSTINSTALL_MTIME_WINDOW 覆盖
  5. 对于每个新修改的文件(扫描 A/B),钩子会伪造一个合成 PostToolUse:Write 载荷,并通过管道传给现有的 shim——shim 的锁文件和清单审计器原样运行,没有重复逻辑
  6. 每个文件的信号被拼接成单个 hookSpecificOutput JSON,发送给父代理

它捕获了 Pre-Install 捕获不到的内容: 传递依赖漏洞。一个看起来干净的 bundle install 可能会拉取 [email protected](CVE-2025-27610)作为 sinatra 的传递依赖——用户从未输入 rack,因此 Pre-Install 看不到它,但 Post-Install 会读取解析后的 Gemfile.lock 并报告该 CVE。

范围: 扫描 A 不会重写已解析的版本——自动纠正契约仅适用于 Claude 直接编写的清单。对于传递 CVE,修复方法通常是“更新拥有该传递依赖的直接依赖”,这需要人工判断。扫描 B 确实会自动纠正,因为它通过与 Intercept 模式相同的 shim 路径审计清单。当 transitive 检查级别设置为 off 时(config set checks.transitive off),扫描 A 会跳过。

失败模式: 与其它钩子一样,采用失败开放(fail-open)。任何错误(缺少 shim、载荷格式错误、Python 不可用)都会静默地以 0 退出。

示例警告:``` WARNING: [email protected] in lock file has GHSA-29mw-wpgm-hmr9, GHSA-35jh-r3h4-6jhm

root@kitploit:~
### Post-Agent 模式(Agent 钩子对)

上述四种模式仅在**根会话(root-session)**的工具调用时触发。当根会话通过 `Agent` 工具派发子代理时(许多技能和斜杠命令内部都会这样做),子代理的 Write/Edit/Bash 调用会绕过所有这些模式。Post-Agent 模式正是针对这一空白的反应性安全网。

1. `PreToolUse:Agent` 钩子(`safer-dependencies-pretooluse-agent.sh`)在每次 Agent 派发之前立即运行,并在 `/tmp/.safer-deps-agent-<PPID>-<session_id>.sentinel` 处创建哨兵文件(如果没有可用的会话 id,则回退到仅基于 PPID 的名称)
2. 子代理运行,并可能写入 manifest 或 lockfile
3. `PostToolUse:Agent` 钩子(`safer-dependencies-posttooluse-agent.sh`)在 Agent 调用返回后运行,`find` 出所有比哨兵文件更新的 manifest 和 lockfile,并通过相同的 shim 路径逐一审计
4. 发现结果以 `additionalContext` 形式呈现给根会话的下一轮;哨兵文件随即被移除

嵌套子代理也会被自动覆盖——根的 `PostToolUse:Agent` 只在外部代理的全部工作(包括它派发的任何内容)都已落盘后才触发。唯一的空白是那种不写入 manifest 或 lockfile 的全局安装(`npm install -g …`):没有可扫描的内容。与其他钩子一样,它采取失败开放(fail-open)策略——任何错误(哨兵缺失、shim 缺失、内容不可读)都会静默地以 0 退出。完整的设计理由见 `skills/safer-dependencies.md`。

## 触发条件

当 Claude 出现以下情况时,该技能会自动触发:

**Manifest / 安装操作**
- 在 `package.json`、`requirements.txt`、`Gemfile`、`pom.xml`、`build.gradle`、`Cargo.toml`、`go.mod` 或任何其他受支持的 manifest 中添加或更新包
- 为尚未在 manifest 中声明的包写入 `import`、`require` 或 `use`
- 生成或更新 lockfile(仅检查新增/变更的条目)
- 通过 Bash 运行包管理器安装(`npm install`、`bundle install`、`poetry install`、`uv sync`、`go mod tidy` 等)——Pre-Install 审计命令参数,Post-Install 审计生成的 lockfile
- 编写嵌入了固定版本包管理器安装步骤的 `Dockerfile` 或 CI 工作流(`.github/workflows/*.yml` 等)

**选择与推荐问题**
- 库/框架比较:“我应该用 axios 还是 node-fetch?”、“moment 还是 dayjs?”、“X 和 Y 哪个更好?”
- 推荐请求:“Python 有什么好的 HTTP 客户端?”、“推荐一个 Go 的日志库”、“在 Node 中处理 CSV 用什么包?”
- 版本选择:“我应该用哪个版本的 Django?”、“最新的稳定版 Flask 是哪个?”

**意图使用表达(添加前)**
- “我想用 FastAPI 来做这个”、“我在考虑添加 Celery”、“我们在考虑用 Prisma 作为 ORM”、“我们改用 Tailwind 吧”

**包健康与可信度问题**
- “moment.js 还在维护吗?”、“这个 gem 还在活跃开发吗?”、“X 被废弃了吗?”、“X 达到生命周期结束(EOL)了吗?”、“我能信任这个包吗?”、“faker 最后一次更新是什么时候?”

**脚手架命令**
- `npx create-react-app`、`npm create vite@latest`、`django-admin startproject`、`rails new`、`cargo new` + `cargo add`、“创建一个新的 FastAPI 项目”

**隐式添加包(暗示新依赖的功能请求)**
- “给应用添加 Redis 缓存”、“连接 Postgres”、“添加 JWT 认证”、“编写发送电子邮件的代码”——当 manifest 中尚不存在实现该功能的包时触发

**迁移与移植**
- “从 requests 迁移到 httpx”、“从 CRA 迁移到 Vite”、“从 moment 移植到 date-fns”——审计新引入的包

在以下情况**不会**触发:

- 标准库导入(`os`、`fs`、`java.util.*` 等)
- 已声明且未被修改的依赖
- 关于包内部工作原理的学术性讨论(“解释 React 的 reconciler”、“webpack 的模块解析是如何工作的?”)——比较和选择类问题仍会触发
- 安装操作系统级应用、运行时或 IDE 扩展(Python 本身、Docker、Homebrew、VS Code 扩展)

## 仓库内容

这是一个 **技能 + 钩子(hook)捆绑包**,而不是单个技能文件。完整安装会部署以下这些部分:

| File | Role |
|---|---|
| `skills/safer-dependencies.md` | **技能**(安装后为 `SKILL.md`)。描述审计流程,并包含用于安装/统计的管理模式。 |
| `skills/safer-dependencies-shim.sh` | `PostToolUse:Write`/`Edit` 钩子——审计 manifest + lockfile 的写入,并就地自动修正存在漏洞的版本(拦截模式,Intercept Mode)。 |
| `skills/safer-dependencies-pretooluse-bash.sh` | `PreToolUse:Bash` 钩子——对包管理器安装命令进行前置 OSV 审计;在安装运行前拒绝存在漏洞的具体固定版本(Pre-Install 模式)。 |
| `skills/safer-dependencies-posttooluse-bash.sh` | `PostToolUse:Bash` 钩子——在 Bash 命令之后进行事后审计;捕获新写入 lockfile 中的传递性 CVE、通过 `sed`/`jq`/脚本编辑的 manifest,以及普通 `pip install` 解析后的环境(Post-Install 模式)。 |
| `skills/safer-dependencies-pretooluse-agent.sh` + `skills/safer-dependencies-posttooluse-agent.sh` | `PreToolUse:Agent` + `PostToolUse:Agent` 钩子对——弥补子代理覆盖空白。模式 2–4 仅在根会话工具调用时触发,因此子代理写入的任何 manifest 都会绕过它们。Post-Agent 会在每次 Agent 工具调用返回后审计子代理写入的内容(Post-Agent 模式)。 |
| `skills/scripts/` | 所有钩子共享的 Python 库(`safedep/`)和独立解析器脚本。 |
| `skills/scripts/safer_dependencies_manager.py` | 用于交互式安装、使用统计和安装验证的管理模块。 |

仅靠技能文件是不够的——如果没有钩子,自动调用就取决于 Claude 是否决定使用该技能。要获得完整覆盖,请安装全部五个部分;许多技能和斜杠命令内部都会派发子代理,因此即使你从未显式创建子代理,Post-Agent 钩子对也很重要。(关于为什么单独的技能无法保证覆盖,请参阅 [FAQ.md](https://github.com/robert-auger/safer-dependencies/blob/HEAD/FAQ.md#why-a-skill-alone-is-not-sufficient)。)

## 支持的生态系统

| 生态系统 | Manifest | Lock file |
|-----------|----------|-----------|
| npm | `package.json` | `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml` |
| PyPI | `requirements.txt`, `pyproject.toml`, `Pipfile`, `setup.py`, `setup.cfg` | `Pipfile.lock`, `poetry.lock`, `uv.lock` |
| RubyGems | `Gemfile`, `*.gemspec` | `Gemfile.lock` |
| Maven | `pom.xml`, `build.gradle`, `libs.versions.toml` | -- |
| Go | `go.mod` | `go.sum` |
| Rust | `Cargo.toml` | `Cargo.lock` |
| PHP (Composer) | `composer.json` | `composer.lock` |

## 安装

刚接触该项目?请从 **[GETTING-STARTED.md](https://github.com/robert-auger/safer-dependencies/blob/HEAD/GETTING-STARTED.md)** 开始。简版说明:```bash
git clone https://github.com/robert-auger/safer-dependencies /tmp/safer-dependencies
python3 /tmp/safer-dependencies/skills/scripts/safer_dependencies_manager.py interactive_install

安装程序会提示选择作用域(全局 vs 项目)以及要启用的钩子,然后为你写入 settings.json — 包括钩子条目 和 权限允许列表,使该技能的检查命令在每次审计时无需审批提示即可运行。

其他与安装相关的内容全部位于 INSTALLATION.md,这是安装机制的唯一参考文档:手动逐文件安装(全局和项目级)、Windows 专属说明、Post-Agent 钩子、权限允许列表、验证安装、更新、固定到发布标签以及卸载。

安装后,日常管理可通过自然语言与 Claude 交互来完成 — install safer-dependencies(重新运行 / 更改钩子)、show safer-dependencies stats、check safer-dependencies setup — 或通过 /safer-dependencies 菜单。更新同样可在会话内完成:/safer-dependencies update 应用最新版本(update --check 用于试运行,update --rollback 用于回滚);信任模型见 INSTALLATION.md。

平台说明: 支持 macOS、Linux 和 Windows。Windows 需要 Git for Windows(提供 bash)以及位于 PATH 中的 Python 3 — 无需 WSL。迄今为止的实操测试主要聚焦于 macOS 和 Windows;Linux 支持通过自动化 CI 矩阵进行验证。

配置

安装后有两项内容可配置:

  • 权限允许列表 — 预先批准该技能的只读检查命令(精确形式的 npm audit / bundle audit 规则以及该技能自身的解析脚本),使每次审计都无需审批提示即可运行;curl 永远不会被预先批准,而 npm view / pip-audit 可通过 Convenience 配置文件选择启用。交互式安装程序会为你写入核心条目;手动安装则需手工添加完整块。完整块及设计理由:INSTALLATION.md → 权限允许列表。
  • 安全策略 — 发布年龄冷却窗口/模式,以及每种检查类型的逐项 off/warn/block 级别,通过 /safer-dependencies config 编辑,并存储在 ~/.config/safer-dependencies/config.toml 中。模式与级别语义:skills/references/configuration.md。

警告级别

级别

审计日志

每次检查都会以单行 JSON 记录到 ~/.claude/safer-dependencies-audit-YYYY-MM.log(每个日历月一个文件,其中 YYYY-MM 为 UTC 年月)。可通过 SAFE_DEP_AUDIT_LOG 环境变量覆盖完整路径(设置后不再追加日期后缀)。当文件超过 SAFE_DEP_LOG_MAX_BYTES 时还会按大小轮转(默认 10 MiB;设为 0 可禁用)。设置 SAFE_DEP_MODEL 可覆盖写入每条记录 source.model 的模型值 — 适用于不同模型版本之间的 A/B 对比。

所有五种模式都追加到同一个文件。每条记录都包含一个 source 块(schema 2.2),用于标识写入它的组件:

source.model 记录会话中处于活动状态的 Claude Code 模型(例如 "claude-sonnet-4-6")。自 schema 2.1+ 起存在;由旧版安装写入的条目会省略该字段。当该字段缺失时,stats 命令会优雅降级为 "unknown"。

使用 jq 按 source.component 过滤:```bash jq -r '.source.component' audit.log | sort | uniq -c | sort -rn jq -c 'select(.source.component == "bash.pretooluse")' audit.log

Surface every silent fail-open across all hooks:

jq -c 'select(.source.mode == "fail_open") | {component: .source.component, reason: .fail_open.reason, ts}' audit.log

root@kitploit:~
为了便于分析,可以让 Claude 提供使用统计信息,而不是手动解析日志:```
"Show safer-dependencies stats for the last month"

这提供了从这些审计日志中提取的活动、安全影响和性能指标的人类可读摘要。

条目形状(schema 2.2)。 三种不同的形状共享相同的 ts / schema / source 头部:

审计条目:拦截模式运行完整流水线(来源、版本年龄、OSV、废弃/过时、域名仿冒、签名),因此所有数组都能填充。预安装模式目前仅运行 OSV,因此 abandoned / stale / typosquat / signatures 始终为空。安装后分发(lockfile 审计)写入到 shim.posttooluse,其中 findings 由锁文件审计器产生的 WARNING: 字符串填充。notes 数组携带信息性 NOTE: 信号(例如 manifest-skipped-because-unpinned)。

Schema 2.2 以增量方式向 lockfile 审计条目添加了四个字段:lockfile、manifest_ref、relation_summary(每个被标记包相对于同级 manifest 的直接/传递/未知分类),以及一个 policy 块,记录当前生效的 transitive 层级。该版本升级向后兼容:2.1 条目的读取者能够容忍新字段,并且 source.model 字段从 2.1 起仍然存在。```json { "ts": "2026-04-19T12:34:56Z", "schema": "2.2", "source": { "component": "shim.posttooluse", "script": "shim.sh", "hook": "PostToolUse:Write", "tool": "Write", "mode": "intercept", "model": "claude-sonnet-4-6" }, "file": "/path/to/project/package.json", "ecosystem": "npm", "checked": ["[email protected]", "[email protected]"], "findings": ["UPDATED: express 4.18.2 → 4.22.1 (HIGH: 1 CVE fixed)"], "abandoned": [], "stale": [], "typosquat": [], "unknown": [], "signatures": [], "notes": [], "clean": ["[email protected]"] }

root@kitploit:~
预安装模式示例 (Bash 钩子,易受攻击的 PIN 被拒绝):```json
{
  "ts": "2026-04-23T06:56:21Z",
  "schema": "2.2",
  "source": {
    "component": "bash.pretooluse",
    "script": "pretooluse-bash.sh",
    "hook": "PreToolUse:Bash",
    "tool": "Bash",
    "mode": "intercept",
    "model": "claude-sonnet-4-6"
  },
  "file": "bash:npm install [email protected] [email protected]",
  "ecosystem": "npm",
  "checked": ["[email protected]", "[email protected]"],
  "findings": [
    "BLOCKED: [email protected] GHSA-35jh-r3h4-6jhm (CVSS:3.1/...): Command Injection in lodash"
  ],
  "abandoned": [],
  "stale": [],
  "typosquat": [],
  "unknown": [],
  "signatures": [],
  "notes": [],
  "clean": ["[email protected]"]
}

Fail-open 模式示例(Post-Install Bash 钩子在无相邻 shim 的情况下被调用 — 安装损坏):```json { "ts": "2026-05-03T07:14:11Z", "schema": "2.2", "source": { "component": "bash.posttooluse", "script": "safer-dependencies-posttooluse-bash.sh", "hook": "PostToolUse", "tool": "Bash", "mode": "fail_open", "model": "claude-sonnet-4-6" }, "fail_open": { "reason": "shim_missing", "detail": "/home/alice/.claude/skills/safer-dependencies" } }

root@kitploit:~
A fail-open 条目表示:“该钩子已触发,但由于缺少某个先决条件而提前退出,未执行审计。”使用上面的 jq 过滤器(`select(.source.mode == "fail_open")`)来找出日志中每一个静默的防护失效事件。

当 shim 以 dry-run 模式运行时(`SAFE_DEP_DRY_RUN=1`),条目还会包含 `"mode": "dry_run"`,以便事后分析可以过滤掉仅审计的调用。

## 要求

- Python 3.9+(钩子会检测此版本,并在较旧的解释器上以 fail-open 方式运行)
- `curl`(用于 registry API 调用和 OSV 漏洞检查)
- 生态系统工具(可选,如果缺失,技能会回退到 OSV API):
  - `npm` 用于 npm 包
  - `pip-audit` 用于 Python 包
  - `bundle` 用于 Ruby 包
  - `dependency-check` 用于 Java 包

## 常见问题

设计决策的理由(为什么使用 `PostToolUse` 而不是 `PreToolUse`、为什么不验证签名、为什么脚本和 shim 是重复的、技能加载的陷阱等)记录在 [`FAQ.md`](https://github.com/robert-auger/safer-dependencies/blob/HEAD/FAQ.md)。
下载工具
REGRESSION:
MAJOR-UPDATE-CONFIRM:
  • Claude 会以系统提醒的形式接收这些信号,并执行后续工作(查找受影响的 import、运行测试、为破坏性变更进行重构)
  • ls
    cat
    git status
    sed -i
    jq
    唯一
    Write
    Edit
  • 扫描 C — 已解析环境。 普通的 pip install / pip install -r requirements.txt 不会写入锁文件,因此扫描 A 永远看不到解析后的依赖树。在 pip 形态的安装之后,扫描 C 使用只读的 list --format=json 重新调用同一个 pip,并对完整解析后的环境(直接 + 传递)执行 OSV 检查。
  • 含义
    示例
    CRITICAL停止并询问用户检测到 typosquat(名称仿冒),签名被篡改
    HIGH警告并继续已知 CVE,包年龄 < 30 天
    MEDIUM警告并继续版本年龄 < 7 天,缺少签名
    LOW警告并继续未签名的 Ruby gem(符合预期)
    source.component写入者触发
    shim.posttooluseshim.sh清单或锁文件写入(拦截模式,安装后分发)
    shim.install_errorshim.shShim 预检安装失败
    bash.pretoolusepretooluse-bash.shBash 安装命令(预安装模式)
    bash.posttooluseposttooluse-bash.sh安装后 Bash 钩子本身,在到达 shim 之前失败开放(fail-open)时
    agent.pretoolusepretooluse-agent.sh预留给 Pre-Agent 失败开放事件(该钩子本身在成功时目前保持静默)
    agent.posttooluseposttooluse-agent.shPost-Agent 钩子失败开放事件(例如 shim 缺失、python_missing)
    manual.skill运行正常模式(Normal Mode)的 Claude内联调用的手动审计
    形状写入时机区分字段
    审计条目Manifest / lockfile / bash-install 审计file, ecosystem, checked, findings, abandoned, stale, typosquat, unknown, signatures, notes, clean
    安装错误条目Shim 预检安装错误(组件 shim.install_error)install_error, shim_dir, scripts_dir
    Fail-open 条目任何钩子入口点因 helper_missing / shim_missing / python_missing 而提前退出。source.mode 为 "fail_open"fail_open: { reason, detail? }