
Агностичный к хосту предварительный хук безопасности для агента кодирования: обнаруживает паттерны пользовательского ввода с помощью Semgrep и выдает детерминированные рекомендации по безопасности без использования LLM.
Контрольно-пропускной пункт безопасности для ИИ-инструментов для написания кода. Он проверяет каждый файл, который пишет ИИ-ассистент, и останавливает опасные до того, как они попадут на диск.
ИИ-ассистенты для написания кода (Claude Code, Codex, …) пишут код быстро — в том числе код, который обрабатывает такие вещи, как пароли, email, ключи API или необработанный пользовательский ввод. Ассистент может легко передать эти данные напрямую в запрос базы данных, команду оболочки или HTTP-ответ, не задумываясь о безопасности.
VibeGate располагается между ассистентом и вашей файловой системой. Каждый раз, когда ассистент пытается записать или отредактировать файл, VibeGate сначала сканирует новый код:
В самом анализе не участвует LLM — это быстрый, детерминированный статический анализ, так что он никогда ничего не выдумывает и не тратит ваши токены.
Вот полный список того, что в настоящее время проверяет VibeGate:
| Проверка | Что выявляет | Результат |
|---|---|---|
| Внедрение команд (Command injection) | Несанированный ввод достигает команды оболочки | Блокирует |
| SQL-инъекция (SQL injection) | Несанированный ввод достигает запроса базы данных | Блокирует |
| NoSQL-инъекция (NoSQL injection) | Тело запроса напрямую используется как фильтр базы данных | Блокирует |
| Инъекция шаблонов (SSTI) | Сам исходный код шаблона, а не только его данные, поступает из пользовательского ввода | Блокирует |
| Небезопасная десериализация (Insecure deserialization) | Недоверенные данные попадают в небезопасный десериализатор (pickle, небезопасный YAML, ...) | Блокирует |
| Path traversal | Несанированный ввод достигает операций чтения, записи или удаления файла | Блокирует |
| XXE | Недоверенный XML обрабатывается с включёнными внешними сущностями | Блокирует |
| XSS | Несанированный ввод отображается как необработанный HTML | Блокирует |
| Неограниченная загрузка файлов | Имя самого загруженного файла используется для построения пути сохранения | Блокирует |
| SSRF | Сервер загружает URL, который не является жёстко заданным | Предупреждает |
| Открытое перенаправление (Open redirect) | Цель перенаправления не является жёстко заданной | Предупреждает |
| Массовое присваивание (Mass assignment) | Всё тело запроса передаётся в конструктор или метод обновления модели | Предупреждает |
| Конфиденциальные данные в теле запроса | Email, пароли, токены и т.д., прочитанные из тела запроса | Предупреждает |
| Конфиденциальные данные в URL/в строке запроса | Email, пароли, токены и т.д., прочитанные из строки запроса | Предупреждает |
| Конфиденциальные данные в заголовках | Email, пароли, токены и т.д., прочитанные из заголовков запроса | Предупреждает |
| Путь к файлу из пользовательского ввода | В качестве пути к файлу используется переменная, а не жёстко заданная строка | Предупреждает |
| Аргументы командной строки | Данные поступают из аргументов командной строки | Предупреждает |
| Стандартный ввод (stdin) | Данные поступают из stdin | Предупреждает |
| Переменные окружения | Данные поступают из переменной окружения | Предупреждает |
| Непривязанное действие GitHub (Unpinned GitHub Action) | В рабочем процессе используется изменяемый тег (@v4) вместо SHA коммита | Предупреждает |
Небезопасный pull_request_target | В рабочем процессе используется триггер pull_request_target | Предупреждает |
| Логирование учётных данных | Пароль, ключ API или токен передаётся в print/console.log/логгер | Предупреждает |
| Жёстко заданный секрет | Переменная, названная как секрет, получает значение, похожее на реальное литеральное | Предупреждает |
Полный актуальный список находится в guidance.TECHNICAL_RISKS и
formatter.BLOCKING_CATEGORIES, на случай, если эта таблица устареет.
┌───────────────────────────────┐
│ Вы просите Claude Code │
│ написать или изменить файл │
└───────────────┬───────────────┘
│
▼
┌───────────────────────────────┐
│ Claude Code пытается │
│ сохранить файл │
│ (инструмент Write/Edit) │
└───────────────┬───────────────┘
│
▼
┌───────────────────────────────┐
│ Hook VibeGate │
│ (запускается автоматически, │
│ до сохранения файла) │
└───────────────┬───────────────┘
│
сканирует новый код с помощью Semgrep
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────────┐ ┌────────────────────┐ ┌──────────────────────┐
│ Рискованный ввод │ │ Рискованный ввод, │ │ Рискованный ввод │
│ не найден │ │ но низкий риск │ │ достигает │
│ │ │ (например, │ │ критического │
│ │ │ отображается │ │ приёмника │
│ │ │ в HTTP-ответе) │ │ (SQL/команда/RCE, │
│ │ │ │ │ инъекция шаблонов) │
└─────────┬──────────┘ └─────────┬──────────┘ └───────────┬──────────┘
│ │ │
▼ ▼ ▼
Файл сохранен, Файл сохранен, Файл НЕ сохранен.
ничего не показано. плюс предупреждение в Claude Code видит
терминале с указанием причину блокировки
риска и способа и получает указание
исправления. что исправить.
Короче: безопасный код проходит без изменений, рискованный, но выживаемый код сохраняется с предупреждением, а код, находящийся в шаге от таких вещей, как SQL-инъекция, внедрение команд или удалённое выполнение кода, останавливается до того, как попадёт на диск.
Если в самом VibeGate возникает неожиданная ошибка, он всегда разрешает запись — ошибка в хуке никогда не должна быть причиной блокировки вашей работы.
Каждое предупреждение и блокировка также содержат явную инструкцию, которая говорит Claude Code упомянуть находку в своём ответе вам, а не просто исправить её молча. Именно это делает активность VibeGate видимой в диалоге, а не только в терминальном логе, куда вам пришлось бы специально заглядывать.