Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

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

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、打字劫持、废弃、版本年龄问题及哈希完整性。

查看仓库
301341个月前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
# 面向 Claude Code 的更安全依赖管理

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

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

> **新手入门?** [GETTING-STARTED.md](https://github.com/robert-auger/safer-dependencies/blob/main/GETTING-STARTED.md) 可在大约五分钟内带你从零开始完成安装。

> **安全与隐私:** 请参阅 [SECURITY.md](https://github.com/robert-auger/safer-dependencies/blob/main/SECURITY.md)(漏洞披露)、[PRIVACY.md](https://github.com/robert-auger/safer-dependencies/blob/main/PRIVACY.md)(数据外发、无遥测)以及 [CAPABILITIES.md](https://github.com/robert-auger/safer-dependencies/blob/main/CAPABILITIES.md)(该工具防御什么、不防御什么)。

> **许可证(源代码可用——非 OSI“开源”):** 可免费用于自身目的的使用和修改,**包括营利性/公司内部使用以及构建你销售的产品**。仅当你要将软件*本身*商业化时才**需要**单独的付费许可证——即销售它、将其打包进销售的产品或服务中,或向第三方有偿提供其功能(包括托管/SaaS/API)。再分发和衍生作品必须保留许可证并注明本项目来源。请参阅 **[LICENSE](https://github.com/robert-auger/safer-dependencies/blob/main/LICENSE)**(第 4 节为商业限制);商业许可证申请请通过 [github.com/robert-auger](https://github.com/robert-auger)。

## 目录

- [快速开始](#getting-started) — 约五分钟完成安装
- [功能说明](#what-it-does)
- [触发条件](#what-triggers-it)
- [仓库内容](#whats-in-this-repo)
- [支持的生态系统](#supported-ecosystems)
- [安装](#install)
  - [配置](#configuration)
  - [修改冷却期](#changing-the-cooldown-period)
- [警告级别](#warning-levels)
- [工作原理](#how-it-works)
  - [普通模式(手动)](#normal-mode-manual)
  - [拦截模式(自动)](#intercept-mode-automatic)
  - [安装前模式(Bash 钩子)](#pre-install-mode-bash-hook)
  - [安装后模式(Bash 钩子)](#post-install-mode-bash-hook)
  - [代理后模式(代理钩子对)](#post-agent-mode-agent-hook-pair)
- [审计日志](#audit-log)
- [系统要求](#requirements)
- [常见问题](#faq)

## 快速开始

**[GETTING-STARTED.md](https://github.com/robert-auger/safer-dependencies/blob/main/GETTING-STARTED.md)** 可在大约五分钟内带你从零开始完成安装——包括前置条件、交互式安装和验证。如需完整的安装参考(全局/项目/手动安装、Windows 特定说明、[权限白名单](https://github.com/robert-auger/safer-dependencies/blob/main/INSTALLATION.md#permissions-allowlist)、更新和卸载),请参阅 **[INSTALLATION.md](https://github.com/robert-auger/safer-dependencies/blob/main/INSTALLATION.md)**。

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

## 功能说明

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

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

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

## 触发条件

该技能在 Claude 执行以下操作时自动触发:

**清单 / 安装操作**
- 在 `package.json`、`requirements.txt`、`Gemfile`、`pom.xml`、`build.gradle`、`Cargo.toml`、`go.mod` 或任何其他受支持的清单中添加或更新包
- 为清单中尚未声明的包写入 `import`、`require` 或 `use`
- 生成或更新锁文件(仅检查新增/变更条目)
- 通过 Bash 运行包管理器安装(`npm install`、`bundle install`、`poetry install`、`uv sync`、`go mod tidy` 等)——安装前审计命令参数,安装后审计生成的锁文件
- 写入嵌入了固定包管理器安装步骤的 `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 到达生命周期终点了吗?”、“我能信任这个包吗?”、“faker 上次更新是什么时候?”

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

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

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

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

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

## 仓库内容

这是一个**技能 + 钩子捆绑包**,而非单个技能文件。完整安装会部署以下组件:

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

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

## 支持的生态系统

| 生态系统 | 清单 | 锁文件 |
|-----------|----------|-----------|
| 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/main/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](https://github.com/robert-auger/safer-dependencies/blob/main/INSTALLATION.md)** 中,这是安装机制的唯一参考文档:手动逐文件安装(全局和项目级)、Windows 特定说明、Post-Agent 钩子、[权限白名单](https://github.com/robert-auger/safer-dependencies/blob/main/INSTALLATION.md#permissions-allowlist)、验证安装、更新、固定到发布标签以及卸载。

安装完成后,日常管理可通过自然语言与 Claude 交互——`install safer-dependencies`(重新运行/更改钩子)、`show safer-dependencies stats`、`check safer-dependencies setup`——或通过 `/safer-dependencies` 菜单。更新也可以在会话内完成:`/safer-dependencies update` 应用最新版本(`update --check` 为试运行,`update --rollback` 用于回滚);信任模型请参阅 [INSTALLATION.md](https://github.com/robert-auger/safer-dependencies/blob/main/INSTALLATION.md#in-session-self-updater-safer-dependencies-update)。

> **平台说明:** 支持 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 → 权限白名单](https://github.com/robert-auger/safer-dependencies/blob/main/INSTALLATION.md#permissions-allowlist)。
- **安全策略** — 发布年龄冷却窗口/模式,以及每种检查类型的 `off`/`warn`/`block` 分级设置,通过 `/safer-dependencies config` 编辑,并存储在 `~/.config/safer-dependencies/config.toml` 中。架构和分级语义:[`skills/references/configuration.md`](https://github.com/robert-auger/safer-dependencies/blob/main/skills/references/configuration.md)。

### 更改冷却期

冷却期(在配置中称为 **cooloff**)是发布版本必须达到的最低年龄,之后该技能才会选择它——默认为 **7 天**。要更改它,请询问 Claude 或直接运行配置命令:```
/safer-dependencies config set cooloff.days 14     # require releases to be 14+ days old
/safer-dependencies config set cooloff.mode block  # gate strength: off | warn | block (default: warn)
/safer-dependencies config unset cooloff.days      # revert to the 7-day default
/safer-dependencies config                         # show effective values and where each comes from
```
相同的动词在 Claude 会话之外同样适用:```bash
python3 skills/scripts/safer_dependencies_manager.py config set cooloff.days 14
```
该设置持久化在 `~/.config/safer-dependencies/config.toml`(`[cooloff]` 部分);`SAFE_DEP_COOLOFF_DAYS` 和 `SAFE_DEP_COOLOFF_MODE` 环境变量会在每次会话中覆盖该文件。需要了解三种行为:`mode = "off"` 会完全从版本选择中移除年龄过滤器;CVE 驱动的重写会绕过该门槛,因此安全修复绝不会因过新而被阻止;该门槛覆盖 npm、PyPI、RubyGems 和 crates.io——Maven 和 Go 有意不设门槛。完整语义请参阅:[`skills/references/configuration.md`](https://github.com/robert-auger/safer-dependencies/blob/main/skills/references/configuration.md)。

## 警告级别

| 级别 | 含义 | 示例 |
|-------|---------|---------|
| CRITICAL | 停止并询问用户 | 检测到拼写劫持、签名被篡改 |
| HIGH | 警告并继续 | 已知 CVE、包发布不足 30 天 |
| MEDIUM | 警告并继续 | 版本发布不足 7 天、缺少签名 |
| LOW | 警告并继续 | 未签名的 Ruby gem(预期情况) |

## 工作原理

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

### 正常模式(手动)

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

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

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

### 拦截模式(自动)

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

1. Claude 使用最初请求的版本写入清单文件(例如 `package.json`)——文件会落到磁盘上
2. `PostToolUse` 钩子在写入完成后立即触发,并调用 `safer-dependencies-shim.sh`
3. 该 shim 读取文件、解析声明的包,并运行所有安全检查(拼写劫持、废弃、CVE、过时、哈希固定)
4. 如果需要修正,shim 会**就地重写清单**,使用安全版本(或移除没有安全版本的条目)
5. shim 通过 stdout 上的 `hookSpecificOutput.additionalContext` 发出信号(`UPDATED:`、`BLOCKED:`、`WARNING:`、`STALE:`、`MAJOR-UPDATE-CONFIRM:`、`REFACTOR-REQUIRED:`、`REGRESSION:`、`TYPOSQUAT-CONFIRM:`、`VERIFY:`、`CLEAN:`)。当审计日志显示同一(文件、包)此前已被修正到相同的安全目标时,`REGRESSION:` 会先于 `MAJOR-UPDATE-CONFIRM:` 出现——也就是说,子代理或过时计划重新引入了已知易受攻击的版本,编排器应恢复先前已批准的版本,而不是重新决定主版本升级。
6. Claude 会以系统提醒的形式接收这些信号,并执行后续工作(查找受影响的导入、运行测试、为破坏性变更进行重构)

**设计说明——形状 C(写入后修正):** 该钩子不会阻止写入。每个易受攻击的版本会先落到磁盘上,然后在同一工具使用周期内被自动修正。这是相对于 `PreToolUse` 阻止式设计的有意选择——权衡取舍请参阅 [FAQ.md](https://github.com/robert-auger/safer-dependencies/blob/main/FAQ.md#why-posttooluse-post-write-corrective-instead-of-pretooluse-pre-write-blocking-for-the-manifest-path)。

**示例信号:**```
UPDATED: aiohttp 3.8.5 → 3.9.0 (HIGH: 33 CVEs fixed)
```
父代理使用这些信号来识别受影响的代码并按需重构。

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

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

1. Claude 尝试调用 Bash 工具(例如 `npm install [email protected]`)
2. `PreToolUse` 钩子在调用执行前触发,并调用
   `safer-dependencies-pretooluse-bash.sh`
3. 一个纯 bash 早期过滤器在约 115 毫秒内短路非包管理器命令
   (不调用 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 脚本

**为何在拦截模式之外还需要此模式:** 写入后垫片
对 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` 直接下载。
> 此钩子尚不能识别这些调用。如果您经常使用它们,
> 现有的写入后垫片仍会捕获落入清单中的任何内容,
> 但预取保护仅适用于上述列出的生态系统。已作为后续事项跟踪。

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

| PM | 动词 | 具体固定版本语法 |
|---|---|---|
| `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`)以及
未指定版本会在安装后传递到拦截模式——写入后垫片会审计解析器选择的任何内容。
自动重写为安全版本已作为后续事项排队。

**故障模式:** 故障开放。任何错误(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.
```
### 安装后模式(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`)。这弥补了 Pre-Install 无法看到的**传递性 CVE 缺口**:用户输入了 `pkg@version`,但解析器可能拉入了数十个无人指定的传递依赖。
- **扫描 B — 清单文件。** 在任何*不在*只读黑名单(`ls`、`cat`、`git status` 等)上的 Bash 命令之后,审计新修改的清单文件。这是通过 `sed -i`、`jq` 或脚本进行清单编辑时的**唯一**兜底方案——这些操作绕过了 Intercept Mode 所钩挂的 `Write`/`Edit` 工具。
- **扫描 C — 解析后的环境。** 普通的 `pip install` / `pip install -r requirements.txt` 不会写入锁文件,因此扫描 A 永远看不到解析后的依赖树。在 pip 形态的安装之后,扫描 C 会以只读的 `list --format=json` 重新调用相同的 pip,并对完整解析后的环境(直接 + 传递依赖)进行 OSV 检查。

扫描的运行方式:

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 Mode 相同的 shim 路径审计清单文件。当 `transitive` 检查层级设置为 `off`(`config set checks.transitive off`)时,扫描 A 会跳过。

**故障模式:** 故障开放,与其他钩子相同。任何错误(shim 缺失、载荷格式错误、Python 不可用)都会静默地以退出码 0 结束。

**WARNING 示例:**```
WARNING: [email protected] in lock file has GHSA-29mw-wpgm-hmr9, GHSA-35jh-r3h4-6jhm
```
### 代理后模式(Agent Hook 配对)

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

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 …`):此时没有可扫描的内容。与其他钩子一样,它采用失败开放策略——任何错误(哨兵缺失、shim 缺失、payload 不可读)都会静默地以退出码 0 结束。完整的设计原理见 `skills/safer-dependencies.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.component` | 写入方 | 触发时机 |
|---|---|---|
| `shim.posttooluse` | `shim.sh` | Manifest 或 lockfile 写入(拦截模式、安装后派发) |
| `shim.install_error` | `shim.sh` | shim 预检安装失败 |
| `bash.pretooluse` | `pretooluse-bash.sh` | Bash 安装命令(预安装模式) |
| `bash.posttooluse` | `posttooluse-bash.sh` | 安装后 Bash 钩子本身,在到达 shim 之前失败开放时 |
| `agent.pretooluse` | `pretooluse-agent.sh` | 保留用于预代理失败开放事件(该钩子本身在成功时保持静默) |
| `agent.posttooluse` | `posttooluse-agent.sh` | 代理后钩子失败开放事件(例如 shim 缺失、python_missing) |
| `manual.skill` | 运行普通模式的 Claude | 内联手动审计调用 |

`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
```
为了更方便地进行分析,可以请 Claude 提供使用统计信息,而无需手动解析日志:```
"Show safer-dependencies stats for the last month"
```
此内容提供了从这些审计日志中提取的活动、安全影响和性能指标的人类可读摘要。

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

| 形态 | 写入时机 | 区分字段 |
|---|---|---|
| **审计条目** | 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` |
| **故障开放条目** | 任何钩子入口点因 `helper_missing` / `shim_missing` / `python_missing` 而提前退出。`source.mode` 为 `"fail_open"` | `fail_open: { reason, detail? }` |

审计条目:拦截模式运行完整流水线(来源、版本年龄、OSV、废弃/过时、typosquat、签名),因此所有数组均可填充。预安装模式目前仅运行 OSV,因此 `abandoned` / `stale` / `typosquat` / `signatures` 始终为空。安装后分发(lockfile 审计)在 `shim.posttooluse` 下写入,`findings` 由 lockfile 审计器中的 `WARNING:` 字符串填充。`notes` 数组携带信息性 `NOTE:` 信号(例如,因未固定版本而跳过 manifest)。

Schema 2.2 以增量方式为 **lockfile** 审计条目新增了四个字段:`lockfile`、`manifest_ref`、`relation_summary`(对每个被标记包相对于同级 manifest 的直接/传递/未知分类),以及一个记录生效中 `transitive` 层级的 `policy` 块。此升级向后兼容:读取 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]"]
}
```
Pre-Install 模式示例(Bash 钩子,易受攻击的引脚被拒绝):```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]"]
}
```
失败开放模式示例(安装后 Bash 钩子被调用时旁边没有垫片——安装损坏):```json
{
  "ts": "2026-05-03T07:14:11Z",
  "schema": "2.2",
  "source": {
    "component": "bash.posttooluse",
    "script": "safer-dependencies-posttooluse-bash.sh",
    "hook": "PostToolUse",

---

[Read more](https://github.com/robert-auger/safer-dependencies)
下载工具