Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
safer-dependencies — Автоматизированный уровень безопасности зависимостей для ИИ-помощников по кодированию, который проверяет пакеты на наличие CVE, typosquats, заброшенность, проблемы с возрастом версий и целостность хешей в экосистемах npm, PyPI, RubyGems, Maven, Go и Rust. | Kitploit
Инструменты/GitHubGitHub/robert-auger/safer-dependencies
Сканеры уязвимостейDevSecOpsОбнаружение СекретовБезопасность Цепочки Поставок
GitHubrobert-auger/safer-dependencies

safer-dependencies

Автоматизированный уровень безопасности зависимостей для ИИ-помощников по кодированию, который проверяет пакеты на наличие CVE, typosquats, заброшенность, проблемы с возрастом версий и целостность хешей в экосистемах npm, PyPI, RubyGems, Maven, Go и Rust.

Репозиторий
30559 дней назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Safer Dependencies для Claude Code

Когда ИИ-ассистенты по написанию кода, такие как Claude, добавляют пакеты в ваш проект, они часто выбирают ту версию, которая звучит подходяще — не проверяя, есть ли у неё известные уязвимости безопасности, поддерживается ли пакет по-прежнему активно, или не является ли имя опечаткой от вредоносного двойника.

safer-dependencies — это уровень безопасности для Claude Code: он находится между Claude и вашими файлами манифестов и автоматически выполняет свои проверки безопасности: установки с уязвимостями отклоняются до их запуска, а рискованная версия, записанная в манифест, исправляется на диске сразу после записи. Он обнаруживает и исправляет рискованные зависимости — CVE, typosquatting, заброшенные пакеты и проблемы с возрастом версий, а также период охлаждения для совершенно новых релизов — в npm, PyPI, RubyGems, Maven, Go, Rust и PHP (Composer). См. CAPABILITIES.md для точного описания того, что покрывается, а что нет.

Новичок? GETTING-STARTED.md проведёт вас от нуля до рабочей установки примерно за пять минут.

Безопасность и конфиденциальность: см. SECURITY.md (раскрытие уязвимостей), PRIVACY.md (исходящие данные, отсутствие телеметрии) и CAPABILITIES.md (от чего инструмент защищает, а от чего нет).

Лицензия (исходный код доступен — НЕ OSI «открытый исходный код»): Бесплатно для использования и модификации в своих целях, включая коммерческое использование внутри компании и создание продуктов, которые вы продаёте. Отдельная платная лицензия требуется для монетизации самого программного обеспечения — его продажи, включения в продукт или сервис, который продаётся, или предоставления его функциональности третьим лицам за плату (включая хостинг/SaaS/API). Распространение и производные работы должны сохранять лицензию и указывать этот проект. См. (Раздел 4 об ограничении коммерческого использования); запросы на коммерческую лицензию через .

только
как такового
LICENSE
github.com/robert-auger

Содержание

  • Начало работы — от нуля до установки примерно за пять минут
  • Что он делает
  • Что его запускает
  • Что в этом репозитории
  • Поддерживаемые экосистемы
  • Установка
    • Конфигурация
    • Изменение периода охлаждения
  • Уровни предупреждений
  • Как это работает
    • Обычный режим (ручной)
    • Режим перехвата (автоматический)
    • Режим перед установкой (Bash-хук)
    • Режим после установки (Bash-хук)
    • Режим после агента (пара хуков агента)
  • Журнал аудита
  • Требования
  • FAQ

Начало работы

GETTING-STARTED.md проведёт вас от нуля до рабочей установки примерно за пять минут — предварительные требования, интерактивная установка и проверка. Для полного справочника по установке (глобальная/проектная/ручная установка, особенности Windows, список разрешённых разрешений, обновление и удаление) см. INSTALLATION.md.

Повседневное использование: после установки хуков ничего запускать не нужно — safer-dependencies работает автоматически в фоновом режиме. Когда Claude добавляет или устанавливает пакеты, он помечает рискованные зависимости и обновляет уязвимые версии до безопасной на месте — и блокирует установку с известной уязвимостью до её запуска — так что небезопасные пакеты обнаруживаются и исправляются без необходимости вас просить. Вы всё равно можете вызывать его напрямую в любое время: «безопасен ли [email protected]?», «проверь настройку safer-dependencies» или «покажи статистику safer-dependencies».

Что он делает

Когда Claude собирается добавить пакет в ваш проект, safer-dependencies перехватывает действие и выполняет 5 проверок:

  1. Происхождение — официальный реестр, обнаружение typosquatting (npm/PyPI/RubyGems/Maven/crates.io), возраст пакета
  2. Возраст версии — выбирает новейшую стабильную версию, опубликованную 7+ дней назад (окно охлаждения)
  3. Сканирование уязвимостей — OSV API, с нативными инструментами экосистемы (npm audit, pip-audit, bundle audit), когда они доступны
  4. Целостность hash-привязки — для строк PyPI requirements.txt с привязками --hash=sha256:... объявленный хэш проверяется на соответствие опубликованным хэшам PyPI; несовпадение выдаёт WARNING
  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 для пакета, ещё не объявленного в манифесте
  • Генерирует или обновляет lock-файл (проверяются только новые/изменённые записи)
  • Запускает установку через менеджер пакетов через Bash (npm install, bundle install, poetry install, uv sync, go mod tidy и т. д.) — Pre-Install проверяет аргументы команды, Post-Install проверяет полученный lock-файл
  • Записывает Dockerfile или CI-пайплайн (.github/workflows/*.yml и т. д.), содержащие шаги установки с закреплёнными версиями через менеджер пакетов

Вопросы выбора и рекомендаций

  • Сравнение библиотек/фреймворков: «стоит ли использовать axios или node-fetch?», «moment vs dayjs?», «что лучше X или Y?»
  • Запросы рекомендаций: «какой хороший HTTP-клиент для Python?», «порекомендуй библиотеку логирования для Go», «какой пакет обрабатывает CSV в Node?»
  • Выбор версии: «какую версию 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-аутентификацию», «напиши код для отправки email» — срабатывает, когда в манифесте ещё нет пакета для этой возможности

Миграция и перенос

  • «Мигрируй с requests на httpx», «перейди с CRA на Vite», «перенеси с moment на date-fns» — проверяет входящий пакет

Он не срабатывает для:

  • Импортов из стандартной библиотеки (os, fs, java.util.* и т. д.)
  • Уже объявленных зависимостей, которые не изменяются
  • Академического обсуждения внутренней работы пакета («объясни reconciler в React», «как работает модульное разрешение webpack?») — вопросы сравнения и выбора всё же срабатывают
  • Установки приложений уровня ОС, сред выполнения или расширений IDE (сам Python, Docker, Homebrew, расширения VS Code)

Что в этом репозитории

Это набор навык + хуки, а не один файл навыка. Полная установка разворачивает следующие компоненты:

ФайлРоль
skills/safer-dependencies.mdНавык (SKILL.md после установки). Описывает процедуры аудита и включает режим управления для установки/статистики.
skills/safer-dependencies-shim.shХук PostToolUse:Write/Edit — проверяет записи манифестов и lock-файлов и автоматически исправляет уязвимые версии на месте (режим перехвата).
skills/safer-dependencies-pretooluse-bash.shХук PreToolUse:Bash — предварительная OSV-проверка команд установки через менеджер пакетов; отклоняет уязвимые конкретные версии до запуска установки (режим перед установкой).
skills/safer-dependencies-posttooluse-bash.shХук PostToolUse:Bash — проверка после выполнения Bash-команд; выявляет транзитивные CVE в только что записанных lock-файлах, манифестах, отредактированных через sed/jq/скрипты, и в разрешённом окружении обычного pip install (режим после установки).
skills/safer-dependencies-pretooluse-agent.sh + skills/safer-dependencies-posttooluse-agent.shПара хуков PreToolUse:Agent + PostToolUse:Agent — закрывает пробел покрытия субагентов. Режимы 2–4 срабатывают только для вызовов инструментов корневой сессии, поэтому любой манифест, записанный субагентом, обходит их. Post-Agent проверяет то, что записал субагент, после каждого возврата вызова инструмента Agent (режим после агента).
skills/scripts/Общая библиотека Python (safedep/) и отдельные скрипты-резолверы, используемые всеми хуками.
skills/scripts/safer_dependencies_manager.pyМодуль управления для интерактивной установки, статистики использования и проверки настройки.

Одного файла навыка недостаточно — без хуков автоматический вызов зависит от того, решит ли Claude обратиться к навыку. Установите все пять компонентов для полного покрытия; многие навыки и слэш-команды внутренне отправляют субагентов, поэтому пара Post-Agent важна, даже если вы никогда явно не запускаете субагента. (См. FAQ.md о том, почему навык сам по себе не может гарантировать покрытие.)

Поддерживаемые экосистемы

ЭкосистемаМанифестLock-файл
npmpackage.jsonpackage-lock.json, yarn.lock, pnpm-lock.yaml
PyPIrequirements.txt, pyproject.toml, Pipfile, setup.py, setup.cfgPipfile.lock, poetry.lock, uv.lock
RubyGemsGemfile, *.gemspecGemfile.lock
Mavenpom.xml, build.gradle, libs.versions.toml--
Gogo.modgo.sum
RustCargo.tomlCargo.lock
PHP (Composer)composer.jsoncomposer.lock

Установка

Новичок в проекте? Начните с 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

root@kitploit:~
Установщик запрашивает область действия (глобальную или для проекта) и то, какие хуки включить, после чего записывает `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) и Python 3 в `PATH` — WSL не нужен. Практическое тестирование на данный момент сосредоточено на **macOS и Windows**; поддержка Linux проверяется автоматической матрицей CI.

### Конфигурация

После установки можно настроить две вещи:

- **Список разрешений** — заранее одобряет проверочные команды навыка, доступные только для чтения (правила `npm audit` / `bundle audit` в точной форме и собственные скрипты-резолверы навыка), чтобы аудиты выполнялись без запроса на одобрение каждый раз; `curl` никогда не одобряется заранее, а `npm view` / `pip-audit` включаются по желанию через профиль Convenience. Интерактивный установщик записывает основные записи за вас; при ручной установке полный блок добавляется вручную. Полный блок и обоснование: [INSTALLATION.md → Permissions allowlist](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

root@kitploit:~
Настройка сохраняется в `~/.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 | Остановиться и спросить пользователя | Обнаружен typosquat, подделанная подпись |
| HIGH | Предупредить и продолжить | Известная CVE, пакет младше 30 дней |
| MEDIUM | Предупредить и продолжить | Версия младше 7 дней, отсутствует подпись |
| LOW | Предупредить и продолжить | Неподписанный Ruby gem (ожидаемо) |

## Как это работает

Навык работает в пяти режимах (кратко описаны ниже; подробное обоснование архитектуры находится в `skills/safer-dependencies.md`):

### Обычный режим (вручную)

Когда Claude собирается написать `import`, добавить пакет в манифест или обновить lock-файл, навык запускается встроенно в вашем сеансе:

1. Запрашивает реестр пакетов для стабильных версий
2. Автоматически выбирает самую новую версию, опубликованную 7+ дней назад (детерминированно — без суждений LLM)
3. Проверяет известные уязвимости с помощью инструментов экосистемы и API OSV
4. Проверяет подписи пакетов, где это доступно
5. Выдаёт предупреждения при обнаружении проблем, фиксирует точную версию
6. Записывает результат в журнал аудита

Выбор версии выполняется автономными Python-скриптами, входящими в состав навыка, а не LLM, интерпретирующим правила. Команда выводит `SELECTED: <version>`, и Claude использует именно эту версию.

### Режим перехвата (автоматический)

Настройте `.claude/settings.json` с хуком `PostToolUse`, чтобы включить автоматическую, прозрачную проверку пакетов:

1. Claude записывает файл манифеста (например, `package.json`) с изначально запрошенной версией — файл попадает на диск
2. Хук `PostToolUse` срабатывает сразу после завершения записи и вызывает `safer-dependencies-shim.sh`
3. Шим читает файл, разбирает объявленные пакеты и выполняет все проверки безопасности (typosquat, заброшенность, CVE, устаревание, хэш-пиннинг)
4. Если требуются исправления, шим **перезаписывает манифест на месте** безопасными версиями (или удаляет записи, для которых нет безопасной версии)
5. Шим выводит сигналы (`UPDATED:`, `BLOCKED:`, `WARNING:`, `STALE:`, `MAJOR-UPDATE-CONFIRM:`, `REFACTOR-REQUIRED:`, `REGRESSION:`, `TYPOSQUAT-CONFIRM:`, `VERIFY:`, `CLEAN:`) через `hookSpecificOutput.additionalContext` в stdout. `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 для каждой находки + CVSS + кратким описанием, а также подсказкой вызвать навык safer-dependencies
  6. Установка не выполняется — ни сетевых запросов, ни postinstall-скриптов

Зачем это нужно в дополнение к режиму перехвата: пост-записывающий шим не видит Bash. npm install [email protected] выполняется до конца (и postinstall-скрипты запускаются) до того, как сработает аудит; npm install -g typosquat-pkg вообще не записывает манифест проекта. Режим предварительной установки структурно закрывает эти пробелы.

Режим предварительной установки видит только то, что пользователь ввёл (аргументы pkg@version в командной строке). Он не видит транзитивное дерево, которое резолвер фактически установит. Режим после установки (ниже) проверяет lockfile после завершения установки — эти два режима дополняют друг друга, а не дублируют.

Область применения: 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-команду).

Известный пробел: CLI Maven поддерживает прямую загрузку через mvn dependency:get -Dartifact=group:art:version и mvn dependency:copy. Этот хук пока не распознаёт такие вызовы. Если вы используете их регулярно, существующий пост-записывающий шим всё равно перехватит всё, что попадёт в ваш манифест, но защита до загрузки применяется только к экосистемам, перечисленным выше. Отслеживается как последующая задача.

Распознаваемый синтаксис по экосистемам:

PMГлаголыСинтаксис конкретной версии
npm, pnpm, yarn, buninstall, i, add (плюс yarn/pnpm dlx, bun x, yarn create)[email protected], @scope/[email protected]
npx(без глагола — пакет является первой позиционной позицией)[email protected]
denoadd, installnpm:[email protected] (спецификации с префиксом npm)
pip, pip3, pipx, pipenv, uv, uvx, poetryinstall (pip/pip3/pipx/pipenv) / add (uv/poetry) / без глагола (uvx)pkg==1.2.3 (дополнения pkg[extra]==X также обрабатываются)
gem, bundleinstall (gem) / add-v 1.2.3, --version 1.2.3, --version=1.2.3 (отдельный флаг)
goget, install[email protected] (обязательно с префиксом v согласно модулям Go)
cargoadd, 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.
root@kitploit:~
### Режим после установки (Bash-хук)

Настройте `.claude/settings.json` с хуком `PostToolUse:Bash`, чтобы включить
пост-проверку после выполнения Bash-команд. Он запускает **три независимых сканирования**
относительно `cwd` команды, каждое из которых закрывает пробел, который другие хуки не могут охватить:

- **Скан A — lock-файлы.** После успешной команды установки (`npm install`,
  `bundle install`, `poetry install`, `uv sync`, `go mod tidy` и т.д.) проверяет
  недавно изменённые lock-файлы (`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-команды, *не* входящей в денай-лист
  только для чтения (`ls`, `cat`, `git status`, …), проверяет недавно изменённые манифесты.
  Это **единственный** запасной вариант для правок манифестов, сделанных через `sed -i`, `jq` или
  скрипт — они обходят инструмент `Write`/`Edit`, на который завязан Intercept Mode.
- **Скан C — разрешённое окружение.** Обычный `pip install` /
  `pip install -r requirements.txt` не записывает lock-файл, поэтому Скан A никогда не видит
  разрешённое дерево. После установки через pip Скан C повторно вызывает тот же
  pip с read-only `list --format=json` и проверяет через OSV всё разрешённое
  окружение (прямые + транзитивные зависимости).

Как выполняется скан:

1. Claude выполняет вызов инструмента Bash
2. Хук `PostToolUse` срабатывает *после* завершения команды и вызывает
   `safer-dependencies-posttooluse-bash.sh`
3. Чистый bash-ранний фильтр короткозамыкает команды, которые не соответствуют ни одному условию скана, за
   ~115 мс (та же конвенция быстрого пути, что и в Pre-Install), поэтому `ls` / `git` / `cat`
   несут незначительные накладные расходы
4. Каждый скан обходит `cwd` с помощью `find -maxdepth 5` (покрывает структуры монорепозиториев;
   исключает `node_modules`, `.git`, `.venv`, `venv`) в поисках файлов, изменённых в течение
   последних 60 с — переопределяется через `SAFE_DEP_POSTINSTALL_MTIME_WINDOW`
5. Для каждого недавно изменённого файла (Скан A/B) хук формирует синтетический
   payload `PostToolUse:Write` и передаёт его в существующий шим — аудиторы lock-файлов
   и манифестов шима работают без изменений, без дублирования логики
6. Сигналы по каждому файлу объединяются и выводятся как один JSON `hookSpecificOutput`
   родительскому агенту

**Что он ловит, чего не ловит Pre-Install:** транзитивные уязвимости.
Чисто выглядящий `bundle install` может подтянуть `[email protected]` (CVE-2025-27610)
как транзитивную зависимость `sinatra` — пользователь никогда не вводил `rack`, поэтому
Pre-Install не может это увидеть, но Post-Install читает разрешённый
`Gemfile.lock` и сообщает о CVE.

**Область действия:** Скан A не переписывает разрешённые версии — контракт
автоисправления применяется только к манифестам, которые Claude написал напрямую. Для транзитивных CVE
исправление обычно заключается в «обновлении прямой зависимости, которой принадлежит транзитивная», что
требует человеческого суждения. Скан B *выполняет* автоисправление, поскольку он проверяет манифесты
через тот же путь шима, что и Intercept Mode. Скан A пропускается, когда уровень проверки
`transitive` установлен в `off` (`config set checks.transitive off`).

**Режим отказа:** fail-open, как и другие хуки. Любая ошибка (отсутствующий
шим, некорректный payload, недоступный Python) завершается кодом 0 молча.

**Пример WARNING:**```
WARNING: [email protected] in lock file has GHSA-29mw-wpgm-hmr9, GHSA-35jh-r3h4-6jhm

Режим после агента (пара хуков агента)

Четыре режима выше срабатывают только для вызовов инструментов корневой сессии. Когда корневая сессия отправляет субагента (через инструмент Agent — многие навыки и слэш- команды делают это внутренне), вызовы Write/Edit/Bash субагента обходят все эти режимы. Режим после агента — это реактивная страховочная сеть для этого пробела.

  1. Хук PreToolUse:Agent (safer-dependencies-pretooluse-agent.sh) запускается непосредственно перед каждой отправкой агента и создаёт файл-маркер в /tmp/.safer-deps-agent-<PPID>-<session_id>.sentinel (с откатом к имени только с PPID, когда идентификатор сессии недоступен)
  2. Субагент выполняется и может записывать манифесты или файлы блокировок
  3. Хук PostToolUse:Agent (safer-dependencies-posttooluse-agent.sh) запускается после возврата вызова агента, находит с помощью find каждый манифест и файл блокировки новее маркера и проверяет каждый через тот же путь шима
  4. Результаты отображаются как additionalContext для следующего хода корневой сессии; маркер удаляется

Вложенные субагенты покрываются автоматически — PostToolUse:Agent корневой сессии срабатывает только после того, как вся работа внешнего агента (включая всё, что он отправил) окажется на диске. Единственный пробел — глобальная установка, которая не записывает манифест или файл блокировки (npm install -g …): сканировать нечего. Как и другие хуки, он завершается открыто — любая ошибка (отсутствующий маркер, отсутствующий шим, нечитаемая полезная нагрузка) молча выходит с кодом 0. Полное обоснование дизайна находится в skills/safer-dependencies.md.

Журнал аудита

Каждая проверка записывается в ~/.claude/safer-dependencies-audit-YYYY-MM.log (один файл на календарный месяц, где YYYY-MM — год-месяц по UTC) как одна строка JSON. Переопределите полный путь с помощью переменной окружения SAFE_DEP_AUDIT_LOG (при её установке суффикс даты не добавляется). Файлы также ротируются по размеру, когда превышают SAFE_DEP_LOG_MAX_BYTES (по умолчанию 10 МиБ; установите 0 для отключения). Установите SAFE_DEP_MODEL, чтобы переопределить значение модели, записываемое в source.model в каждой записи — полезно для A/B-сравнений между версиями моделей.

Все пять режимов добавляют записи в один и тот же файл. Каждая запись содержит блок source (схема 2.2), определяющий, какой компонент её записал:

source.componentКем записаноТриггер
shim.posttooluseshim.shЗапись манифеста или файла блокировки (режим перехвата, отправка после установки)
shim.install_errorshim.shСбой установки при предварительной проверке шима
bash.pretoolusepretooluse-bash.shКоманда установки Bash (режим перед установкой)
bash.posttooluseposttooluse-bash.shСам хук Bash после установки, когда он завершается открыто до достижения шима
agent.pretoolusepretooluse-agent.shЗарезервировано для событий открытого завершения перед агентом (сам хук в настоящее время молчит при успехе)
agent.posttooluseposttooluse-agent.shСобытия открытого завершения хука после агента (например, отсутствующий шим, python_missing)
manual.skillClaude, выполняющий обычный режимРучной аудит, вызванный встроенно

source.model записывает модель Claude Code, активную в сессии (например, "claude-sonnet-4-6"). Присутствует в схеме 2.1+; записи, созданные более старыми установками, опускают это поле. Команда статистики корректно переходит к "unknown", когда оно отсутствует.

Фильтруйте по source.component с помощью jq:```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"

Это предоставляет удобочитаемые сводки активности, влияния на безопасность и показателей производительности, извлечённые из этих журналов аудита.

Формы записей (схема 2.2). Три различные формы используют один и тот же заголовок ts / schema / source:

ФормаКогда записываетсяОтличительные поля
Запись аудитаАудит манифеста / lockfile / bash-installfile, ecosystem, checked, findings, abandoned, stale, typosquat, unknown, signatures, notes, clean
Запись об ошибке установкиОшибка установки при предварительной проверке шима (компонент 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? }

Записи аудита: режим перехвата (Intercept Mode) выполняет полный конвейер (происхождение, возраст версии, OSV, abandoned/stale, typosquat, подписи), поэтому все массивы могут заполняться. Режим предварительной установки (Pre-Install Mode) сегодня выполняет только OSV, поэтому abandoned / stale / typosquat / signatures всегда пусты. Отправка после установки (аудит lockfile) записывается под shim.posttooluse с findings, заполняемыми строками WARNING: от аудиторов lockfile. Массив notes содержит информационные сигналы NOTE: (например, манифест пропущен, так как не закреплён).

Схема 2.2 добавила — аддитивно — четыре поля к lockfile-записям аудита: lockfile, manifest_ref, relation_summary (классификация direct/transitive/unknown каждого отмеченного пакета относительно парного манифеста) и блок 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:~
Pre-Install Mode example (Bash hook, vulnerable pin denied):```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 Mode example (Post-Install Bash hook called with no shim adjacent — broken install):```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:~
Запись с режимом fail-open означает: «этот хук сработал, но завершился досрочно без аудита, потому что отсутствовало какое-то обязательное условие». Используйте фильтр jq выше (`select(.source.mode == "fail_open")`), чтобы выявить каждое тихое событие потери защиты в вашем журнале.

Когда шим запускается в режиме пробного прогона (`SAFE_DEP_DRY_RUN=1`), записи также содержат `"mode": "dry_run"`, чтобы последующий анализ мог отфильтровать вызовы только для аудита.

## Требования

- Python 3.9+ (хуки проверяют его наличие и переходят в режим fail-open на более старых интерпретаторах)
- `curl` (для вызовов API реестра и проверок уязвимостей OSV)
- Инструменты экосистемы (необязательно, навык переключается на OSV API при их отсутствии):
  - `npm` для пакетов npm
  - `pip-audit` для пакетов Python
  - `bundle` для пакетов Ruby
  - `dependency-check` для пакетов Java

## FAQ

Обоснование проектных решений (почему `PostToolUse` вместо `PreToolUse`, почему подписи не проверяются, почему скрипты и шим дублируются, особенности загрузки навыков и т. д.) задокументировано в [`FAQ.md`](https://github.com/robert-auger/safer-dependencies/blob/main/FAQ.md).
Скачать инструмент