Вайбцех

Хуки в Claude Code в 2026: как настроить блокировку опасных команд за 5 шагов

Опубликовано 12 мин чтенияБазовый
Автор с приложенного фото показывает схему блокировки опасной команды, рядом удивлённый кот.
Что узнаете
  • понимание, что такое локальный хук Claude Code
  • различие между PreToolUse, PostToolUse и веб-хуком
  • схема блокировщика опасных Bash-команд через exit 2
  • список ограничений, обходов и дополнительных слоёв защиты
Применить за 30 мин
Базовый
Что в инструкции
  1. Что такое хуки в Claude Code?
  2. Хук Claude Code и веб-хук: в чём разница?
  3. Какие опасные действия можно остановить хуком?
  4. Как сделать локальный хук для блокировки?
  5. Как установить и проверить хук?
  6. Что делать, если хук пропускает опасную команду?
  7. Почему хук не заменяет sandbox и обычные разрешения?
  8. Вопросы и ответы

Что такое хуки в Claude Code?

Если ты ищешь «хук что это», представь шлагбаум перед командой. Claude выбрал инструмент. До его запуска Claude Code передаёт событие локальному скрипту. Скрипт смотрит на параметры и решает, пропустить действие или остановить его.

PreToolUse работает до инструмента. Это главное для защиты. Если Claude собирается выполнить Bash-команду, хук может проверить поле tool_input.command. Если команда попала под запрет, скрипт возвращает отказ.

PostToolUse работает после инструмента. Для журнала, форматирования или проверки результата это подходит. Запись к этому моменту уже произошла, поэтому отменить её нельзя: файл мог измениться.

Ты можешь блокировать опасные команды до их выполнения» (пер. с англ.)

- Anthropic, How to configure hooks

Хук отличается от обычной инструкции для модели. В CLAUDE.md можно написать правило: не удаляй файлы, не трогай секреты, сначала покажи план. Но это текст для модели. Она может понять его неправильно, забыть о нём или выбрать обходной путь.

Локальный скрипт проверяет событие независимо от формулировки ответа Claude. Поэтому я бы ставил эти механизмы рядом: инструкция объясняет намерение, хук ставит техническую проверку.

Хук Claude Code и веб-хук: в чём разница?

Кот сравнивает локальный хук Claude Code и веб-хук на двух карточках.

Если тебе нужен «веб хук», речь обычно идёт об отправке события наружу. Например, одна система сообщает другой о новом заказе, платеже или изменении статуса. Получатель принимает данные через сеть и выполняет свою логику.

Хук Claude Code живёт внутри процесса работы с проектом. Он запускает локальную shell-команду, получает входные данные через stdin и отвечает кодом выхода и stdout. Внешний сервер для такой проверки не нужен.

Разница видна в таблице:

ХарактеристикаЛокальный хук Claude CodeВеб-хук
Место работыВнутри процесса Claude CodeВнешний сервер
Входные данныеstdin (JSON события)HTTP-запрос
Может остановить инструмент до запускаДа (PreToolUse + exit 2)Нет
Требует внешний серверНетДа

Веб-хук может отправить уведомление о событии во внешний сервис, но не остановит локальный инструмент до запуска.

Для блокировки опасных действий я выбираю локальный PreToolUse. Уведомления и интеграции с внешними системами отправляй через веб-хук. Название одинаковое, место работы разное.

Какие опасные действия можно остановить хуком?

Проблема начинается не только с ошибки Claude. Anthropic описывает approval fatigue: после большого числа запросов человек перестаёт внимательно читать каждое подтверждение и нажимает разрешение почти автоматически.

Со временем это приводит к усталости от подтверждений, когда люди перестают внимательно следить за тем, что именно они разрешают» (пер. с англ.)

- Anthropic, How Claude Code auto mode works

Локальный хук снижает зависимость от такого внимания. Фильтр надо строить вокруг последствий, учитывая, что опасная команда может быть спрятана внутри одной строки. Команда может вызвать оболочку, интерпретатор или готовый скрипт, внутри которого находится опасное действие.

При проверке я бы держал несколько направлений:

  • опасные shell-команды и цепочки команд;
  • python -c, node -e и bash -c;
  • package-manager scripts;
  • удаление или перезапись файлов;
  • команды Git, включая операции с удалённым репозиторием;
  • обращения к секретам и чувствительным файлам;
  • другие инструменты, через которые действие может попасть в файловую систему.

Я бы не давал широкие разрешения на весь Bash, Python, Node или npm run только ради удобства. В таком случае проверка теряет команды, которые способны причинить ущерб.

Я бы начинал с одного узкого правила. Например, блокировал бы конкретные операции с рабочей директорией, .env, базой или Git. Потом добавлял бы тесты на обходы. Большой regex, который никто не понимает, создаёт ложное чувство защиты.

У хука есть и собственный риск. Скрипт запускается с правами пользователя. Изменённый hook или settings.json может стать частью атаки. Конфигурацию из чужого репозитория нельзя считать безопасной только потому, что она лежит локально.

Как сделать локальный хук для блокировки?

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

    Нужен PreToolUse. Он получает параметры инструмента до выполнения. Для Bash matcher должен выбирать Bash-вызовы, а сам скрипт должен работать с полем tool_input.command.

    Создай в проекте файл .claude/settings.json. Подключи в нём локальный обработчик. Точная конфигурация зависит от актуального синтаксиса Claude Code, поэтому перед публикацией сверься с официальной документацией Claude Code Hooks: там полный перечень событий.

    json
    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Bash",
            "hooks": [
              {
                "type": "command",
                "command": ".claude/hooks/block-dangerous.sh"
              }
            ]
          }
        ]
      }
    }
  2. Подготовь локальный скрипт.

    Сделай файл .claude/hooks/block-dangerous.sh. Он получает JSON через стандартный ввод. Из него надо достать фактическое значение tool_input.command, а не проверять только текст запроса Claude.

    В следующем шаблоне опасными считаются несколько очевидных направлений. Это стартовая точка для собственных проверок, а sandbox решает более широкую задачу.

    bash
    #!/usr/bin/env bash
    
    set -euo pipefail
    
    event_json="$(cat)"
    
    command_text="$(
      printf '%s' "$event_json" |
        python -c 'import json, sys; print(json.load(sys.stdin).get("tool_input", {}).get("command", ""))'
    )"
    
    if printf '%s' "$command_text" | grep -Eiq \
      '(^|[;&|()[:space:]])rm([[:space:]]|$)|rm[[:space:]]+-rf|python[[:space:]]+-c|node[[:space:]]+-e|bash[[:space:]]+-c|(^|[[:space:]])tee([[:space:]]|$)|(^|[[:space:]])dd([[:space:]]|$)|git[[:space:]]+push[[:space:]]+--force|\.env'; then
      printf '%s\n' \
        'Команда заблокирована локальным PreToolUse-хуком: проверь последствия и выбери безопасный способ.' \
        >&2
      exit 2
    fi
    
    exit 0

    Код exit 2 здесь обязателен. Обычный ненулевой код не равен блокировке: в практических наблюдениях именно exit 2 останавливает действие.

  3. Оставь безопасные команды штатной проверке.

    В безопасной ветке скрипт не должен возвращать permissionDecision: "allow". Не надо автоматически разрешать всё, что не совпало с фильтром.

    Такая логика сохраняет обычные запросы разрешений Claude Code:

    • опасное совпало - вывести причину в stderr и вернуть exit 2;
    • опасное не совпало - не выносить отдельное разрешение;
    • дальше решение принимает штатная система разрешений.

    permissionDecision: "allow" выглядит удобно, но может отключить стандартные подтверждения для остальных команд. Такой режим оставит всё остальное без вопроса и обойдёт ожидаемую защиту от опасных действий.

  4. Проверь вход и отказ.

    Сначала проверь, что скрипт действительно читает событие из stdin и достаёт tool_input.command. Потом вызови его с тестовым JSON, не запуская разрушительную команду.

    bash
    printf '%s\n' '{"tool_input":{"command":"rm -rf test-directory"}}' |
      .claude/hooks/block-dangerous.sh
    
    printf 'exit code: %s\n' "$?"

    Для заблокированной команды ожидается exit 2. Причина должна попасть в stderr. Реальное удаление в этом тесте не запускается: скрипту передаётся только JSON-текст.

  5. Сделай файл исполняемым.

    Подключение в настройках не заменяет права доступа к скрипту. Дай файлу право на запуск и проверь путь.

    bash
    chmod +x .claude/hooks/block-dangerous.sh
    test -x .claude/hooks/block-dangerous.sh

    Платформенные различия Bash, права доступа и доступность интерпретатора надо сверить с окружением. Для первого варианта я бы не добавлял сеть, внешние разрешения и автоматические коммиты. Чем меньше частей у блокировщика, тем проще понять его поведение.

Практикум полезен именно на этом переходе: там ты собираешь рабочие ограничения руками, а не просто просишь агента «не ломать проект». Хуки, разрешения и проверки становятся частью одной схемы. Пройти практикум

Практикум «Старт»

Три дня живой практики: от идеи до работающего проекта по ссылке

2 000 ₽старт 5 августа, 18:00 МСК

Как установить и проверить хук?

Если ты ищешь «установить хук», начни с пути к скрипту и .claude/settings.json. Настройка может включать событие, matcher и команду обработчика. Проверь, что путь указывает на существующий исполняемый файл.

Дальше проведи пять проверок:

  1. Передай тестовое событие с опасной командой. Скрипт должен вывести причину в stderr и вернуть exit 2.
  2. Передай тестовое событие с безопасной командой. Скрипт не должен возвращать permissionDecision: "allow".
  3. Запусти Claude Code и убедись, что опасное действие останавливается до Bash.
  4. Проверь, что безопасная команда передаётся штатной системе разрешений.
  5. Убедись, что PostToolUse не используется как предохранитель: после записи он уже не отменит изменение.

Есть неприятная особенность. exit 2 точно останавливает инструмент, но Claude не всегда продолжает сценарий сам. Иногда он прекращает ответ и ждёт ручного ввода. В такой ситуации придётся самому решить, что делать дальше, или написать Claude команду продолжить после исправления.

Правильный запуск скрипта тоже не означает автоматическое продолжение работы. Хук отвечает за остановку действия. Он не обязан чинить план агента и выбирать безопасную замену.

Что делать, если хук пропускает опасную команду?

Совпадение по одной строке не даёт полной защиты. Команда rm -rf может исчезнуть из видимого текста и оказаться внутри интерпретатора или другого скрипта. Запись файла можно выполнить через tee, cp, mv или Git. Чтение секрета через Read не закрывает чтение через Bash.

Проверь несколько поверхностей выполнения:

  • Bash-команды и цепочки с ;, &&, ||;
  • python -c, node -e, bash -c;
  • tee, dd, cp, mv;
  • Git-операции;
  • MCP-серверы;
  • subagents;
  • фоновые задачи;
  • симлинки и переименованные копии;
  • сам .claude/settings.json;
  • сам hook-скрипт.

В сообществе Claude Code на Reddit отмечают, что хуки не являются границей безопасности: Any way for Claude Code to circumvent hooks?

Отдельно проверь конфигурацию. Если агент может изменить hook или settings.json, он способен ослабить собственную проверку. Для таких изменений нужен отдельный контроль, включая просмотр diff и подтверждение человеком.

Секреты лучше не держать в рабочей папке открытым текстом. Хук для Read контролирует конкретный вызов Read, но не все способы прочитать тот же файл. Для Bash нужна отдельная проверка.

Я бы не пытался закрыть все обходы одним regex. Сначала выбери последствия, которые нельзя допустить. Потом проверь каждый способ их вызвать. Если риск высокий, добавь sandbox и ручной контроль.

Практикум «Старт»

Три дня живой практики: от идеи до работающего проекта по ссылке

2 000 ₽старт 5 августа, 18:00 МСК

Почему хук не заменяет sandbox и обычные разрешения?

Задумчивый мужчина смотрит на пять слоёв защиты вокруг опасной команды.

PreToolUse полезен как точечный предохранитель. Он может запретить конкретную Bash-команду до запуска. Но он не контролирует автоматически все инструменты, MCP, фоновые процессы и способы обойти строковый фильтр.

Sandbox работает иначе. Он ограничивает доступ к файлам, возможность записи за пределами рабочего каталога и сетевой доступ. Его ограничения распространяются также на программы и subprocesses, запущенные командой.

Обычная система разрешений остаётся отдельным слоем. Без permissionDecision: "allow" безопасная команда может пройти через штатное подтверждение. Человек видит действие и решает, пропускать его или нет.

Version control нужен для восстановления и проверки изменений. Он не отменяет необходимость остановить опасную команду, но помогает увидеть, что реально изменилось. Если проект уже пострадал от неосторожной правки, воспользуйся схемой из статьи Как починить проект после вайб-кодинга.

Собери слои так:

  • узкий PreToolUse для известных опасных действий;
  • sandbox для уменьшения последствий;
  • обычные разрешения без широкого blanket-доступа;
  • version control для diff и отката;
  • проверка человеком перед важными изменениями.

Anthropic формулирует этот принцип прямо:

The deterministic boundary is what gets hit when everything probabilistic misses» (пер. с англ.: «Детерминированная граница: то, что срабатывает, когда всё вероятностное промахивается»)

- Anthropic, How we contain Claude across products

Хук не делает Claude Code безопасным вообще. Он закрывает выбранный риск. На этом месте я останавливаюсь: если нужна полноценная изоляция, одного скрипта недостаточно.

Вопросы и ответы

Вопросы и ответы

Что такое хук в Claude Code?

Хук - локальная shell-команда, которую Claude Code запускает до или после события. Она получает данные через stdin, отвечает через код выхода и stdout. Для блокировки опасной команды используется PreToolUse. Похожим образом ИИ-агент получает доступ к внешним инструментам через MCP.

Как устроена система хуков в Claude Code?

Система состоит из событий, matcher-правил и локальных обработчиков. Обработчик получает параметры инструмента, выполняет проверку и возвращает результат. В Claude Code появились также события PermissionRequest, PermissionDenied, ConfigChange и другие расширения. Подробнее о протоколе интеграций читай в статье MCP или Skills в Claude Code: где хранить инструкцию для повторяемой задачи в 2026.

Как добавить новый хук в проект?

Создай локальный скрипт, подключи его в .claude/settings.json, укажи событие PreToolUse, matcher инструмента и путь к обработчику. После этого проверь права доступа и тестовое событие через stdin.

Как выбрать подходящий хук для блокировки опасных изменений?

Для блокировки до выполнения лучший хук: PreToolUse. PostToolUse подходит для проверки результата или логирования, но не отменяет уже выполненную запись. Для более широкой защиты добавь sandbox и оставь обычные разрешения включёнными.

Где находятся официальные настройки хуков Claude Code?

Проектный файл .claude/settings.json: основной уровень конфигурации. Полный перечень уровней конфигурации и точные расположения пользовательских файлов надо сверять на официальной reference-странице Claude Code Hooks.

Какой скрипт использовать для хука Claude Code?

Для первого блокировщика подходит локальный Bash-скрипт без внешних разрешений и сетевых вызовов. Он читает JSON из stdin, проверяет tool_input.command, пишет причину в stderr и возвращает exit 2 при отказе.

Какая версия скрипта нужна для локального хука?

Отдельная версия скрипта не нужна: это локальный файл в проекте. Важно, чтобы Claude Code поддерживал нужное событие и формат решения. Самое раннее найденное упоминание Hooks в changelog относится к версии 1.0.54; актуальная зафиксированная версия: 2.1.223.

Что такое веб-хук и связан ли он с хуками Claude Code?

Веб-хук отправляет уведомление или данные во внешнюю систему. Локальный хук Claude Code работает внутри жизненного цикла инструмента. Название похоже, но веб-хук не заменяет PreToolUse для блокировки локальной команды.

Как установить локальный хук в Claude Code?

Подключи обработчик через конфигурацию проекта, укажи путь к скрипту и выдай ему право на запуск. После этого протестируй опасное событие без выполнения разрушительной команды и проверь безопасный сценарий.

Где проверить официальную документацию по хукам Claude Code?

Проверяй актуальную страницу Claude Code Hooks и changelog Claude Code - это официальный источник. Там сверяй структуру конфигурации, matcher, формат входного JSON и поддерживаемые решения.

Можно ли блокировать опасную команду только регулярным выражением?

Можно начать с регулярного выражения для выбранных паттернов, но полной защиты оно не даёт. Команда может пройти через интерпретатор, другую оболочку, Git, MCP, фоновые задачи или изменённую конфигурацию. Проверяй последствия и несколько поверхностей выполнения.

Источники

Практикум «Старт»

Три дня живой практики: от идеи до работающего проекта по ссылке

2 000 ₽старт 5 августа, 18:00 МСК

Материал был полезен?
Сергей Мазур
Автор
Сергей Мазур
Основатель Вайбцеха

Собираю продукты с ИИ-агентами и рассказываю, как это делать без программиста.

Читайте также

Термины из инструкции