
Автоматизированный уровень безопасности зависимостей для ИИ-помощников по кодированию, который проверяет пакеты на наличие CVE, typosquats, заброшенность, проблемы с возрастом версий и целостность хешей в экосистемах npm, PyPI, RubyGems, Maven, Go и Rust.
# Safer Dependencies для Claude Code Когда ИИ-ассистенты по написанию кода, такие как Claude, добавляют пакеты в ваш проект, они часто выбирают ту версию, которая звучит подходяще — не проверяя, есть ли у неё известные уязвимости безопасности, поддерживается ли пакет по-прежнему активно, или не является ли имя опечаткой от вредоносного двойника. safer-dependencies — это уровень безопасности для Claude Code: он находится между Claude и вашими файлами манифестов и автоматически выполняет свои проверки безопасности: установки с уязвимостями отклоняются до их запуска, а рискованная версия, записанная в манифест, исправляется на диске сразу после записи. Он обнаруживает и исправляет рискованные зависимости — CVE, typosquatting, заброшенные пакеты и проблемы с возрастом версий, а также период охлаждения для совершенно новых релизов — в 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](#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. **Происхождение** — официальный реестр, обнаружение 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](https://github.com/robert-auger/safer-dependencies/blob/main/FAQ.md#why-a-skill-alone-is-not-sufficient) о том, почему навык сам по себе не может гарантировать покрытие.) ## Поддерживаемые экосистемы | Экосистема | Манифест | Lock-файл | |-----------|----------|-----------| | 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 ``` Установщик запрашивает область действия (глобальную или для проекта) и то, какие хуки включить, после чего записывает `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 ``` Настройка сохраняется в `~/.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` вообще не записывает манифест проекта. Режим предварительной установки структурно закрывает эти пробелы. --- [Read more](https://github.com/robert-auger/safer-dependencies)