Чтобы найти уязвимости в своём коде с помощью ИИ, сначала запустите быстрые детерминированные сканеры (секреты, зависимости, статические правила), а затем давайте агенту для программирования по одному классу уязвимостей и просите проследить, как недоверенные данные проходят через ваш код. Считайте каждую находку утверждением, которое нужно проверить, исправляйте её с регрессионным тестом и всё это время держите агента подальше от настоящих секретов.
Это руководство — об аудите вашего собственного кода, с позиции защиты. Если вы хотите узнать, как не дать навредить самому агенту (prompt injection, разрушительные команды, вредоносные MCP-серверы), сначала прочитайте безопасность AI-агентов для программирования; здесь предполагается, что эти меры уже приняты. Названия инструментов и команды ниже соответствуют официальной документации по состоянию на октябрь 2026 года.
В чём ИИ-аудит силён, а в чём нет
Статические сканеры и агенты для программирования находят разные ошибки, поэтому нужны и те, и другие.
| Детерминированные сканеры | Агент для программирования | |
|---|---|---|
| Сильная сторона | Известные шаблоны, известные уязвимые версии пакетов, форматы секретов | Логика: кто может вызывать этот маршрут, откуда берётся это значение, что упустила проверка |
| Слабая сторона | Пропускают бизнес-логику; шумят на безопасных шаблонах | Ложные срабатывания, пропущенные проблемы, разные ответы при каждом запуске |
| Стоимость | Секунды, воспроизводимо | Токены, медленнее, не воспроизводимо |
| Лучшее применение | Проверка в CI на каждом изменении | Точечный аудит рискованных участков и нового кода |
Агент отлично замечает, например, эндпоинт, который проверяет, что вы вошли в систему, но не проверяет, что заказ, который вы читаете, — ваш. Никакое регулярное выражение этого не увидит. С другой стороны, агент не всегда заметит, что lodash в вашем lock-файле трёхлетней давности; npm audit заметит.
Чего не делает ни один из них: не тестирует работающую систему. Агент читает исходный код в вашей рабочей копии. Неправильно настроенное облачное хранилище, правило файрвола или токен, утёкший в логе чата, ему не видны.
Перед началом: безопасная настройка
Аудит безопасности — задача, в которой в основном читают, так и настройте его.
- Работайте в ветке или в git worktree. Аудит и исправления должно быть легко проверить и легко выбросить.
- Начинайте в режиме только для чтения. В Claude Code для самого аудита используйте plan mode (Shift+Tab или
/plan); в Codex —/permissions→ Read Only или--sandbox read-only. Переходите к правкам, только когда исправляете. - Держите секреты вне досягаемости. Никогда не вставляйте в промпт ключи, токены или содержимое
.env. Если агенту нужно знать, что переменная существует, достаточно её имени. Читать ему стоит.env.exampleс фиктивными значениями. - Используйте учётные данные для разработки. Если агент запускает ваши тесты, эти тесты должны обращаться к локальной или staging-базе с одноразовыми ключами, никогда не к продакшену.
Шаг 1: запустите детерминированные сканеры
Они работают секунды и дают агенту конкретные зацепки. Все они бесплатны для локального запуска.
# Secrets in git history and in the working tree (gitleaks v8.19+)
gitleaks git -v .
gitleaks dir -v .
# Known-vulnerable dependencies
npm audit --audit-level=high
pip-audit -r requirements.txt
# Static analysis rules for your languages
semgrep scan --config auto
Несколько замечаний из официальной документации:
- gitleaks в v8.19.0 разделил старую команду
detectнаgit(сканирование коммитов) иdir(сканирование файлов); старые команды по-прежнему работают, но скрыты из справки. - npm audit
--audit-levelменяет только код выхода, а не отчёт.npm audit fixвыполняет настоящую установку;npm audit fix --forceможет поставить обновления с мажорной версией SemVer, так что не запускайте его вслепую. - pip-audit без аргументов проверяет текущее окружение Python;
-rпроверяет файл requirements. - Semgrep
--config autoзагружает правила, подобранные под ваш проект, из Semgrep Registry, поэтому ему нужен доступ к сети. Добавьте--error, чтобы при находках он завершался с кодом 1, — это то, что нужно в CI.
Сохраните вывод в файл. На шаге 3 вы передадите его агенту, а не будете перепечатывать.
Шаг 2: проверяйте по одному классу уязвимостей
«Найди проблемы с безопасностью в этом репозитории» даёт поверхностный список. Отдельный сфокусированный промпт на каждый класс даёт настоящий анализ. OWASP Top 10:2025 — хорошая карта; вот классы, которые в типичном веб-приложении стоит проверить первыми:
| Класс | Что попросить агента проследить | Типичный признак |
|---|---|---|
| Нарушение контроля доступа | Каждый маршрут, который читает или меняет запись: проверяет ли он, что запись принадлежит вызывающему? | findById(req.params.id) без фильтра по владельцу или арендатору |
| Инъекции (SQL, shell, XSS) | Каждое место, где пользовательский ввод попадает в запрос, команду оболочки или HTML | Конкатенация строк в SQL, exec с вводом, вывод сырого HTML |
| Ошибки аутентификации | Вход, сессии, сброс пароля и работа с токенами | Токены сброса, которые никогда не истекают, нет ограничения частоты на входе |
| SSRF | Каждый серверный запрос, URL которого приходит от пользователя | fetch(req.body.url) без списка разрешённых адресов |
| Секреты в репозитории | Ключи в коде, токены в конфигурации, учётные данные в тестах | Строки, похожие на ключи; gitleaks тут надёжнее |
| Цепочка поставок | Зависимости, скрипты установки, права workflow в CI | Незакреплённые actions, широкие permissions: в workflow |
Промпт, который работает, в plan mode:
Проверь этот репозиторий на нарушения контроля доступа. Не редактируй файлы.
1. Перечисли все HTTP-маршруты, которые читают, обновляют или удаляют запись по ID.
2. Для каждого найди, откуда берётся личность вызывающего и ограничен ли
запрос записями, которыми он владеет (пользователь или арендатор).
3. Сообщай только о маршрутах, где ты можешь показать отсутствующую проверку.
Для каждой находки укажи: file:line, маршрут, откуда берётся ID,
почему существующий middleware это не покрывает, и критичность
(high/medium/low). Если не уверен, так и скажи, а не угадывай.
Повторите ту же схему для инъекций, аутентификации и SSRF. Один класс на разговор держит контекстное окно сфокусированным, и такие проверки можно запускать параллельно в отдельных сессиях.
Для инъекций полезно объяснить агенту, как в вашем стеке выглядит «безопасно», чтобы он не помечал каждый запрос:
Мы везде используем параметризованные запросы через db.query(sql, params).
Найди все места, где SQL, команды оболочки или HTML собираются из данных
запроса без параметров db.query, без execFile с массивом аргументов
или без экранирования шаблонизатора. Игнорируй код в tests/.
Шаг 3: используйте встроенные проверки безопасности
Несколько агентов теперь поставляются с проверкой безопасности, которую не нужно писать самому.
Claude Code /security-review. Официальный справочник команд описывает её как анализ изменений в текущей ветке на уязвимости: она проверяет diff между вашей веткой и веткой по умолчанию origin и ищет риски вроде инъекций, проблем с аутентификацией и утечки данных. Ей нужен remote origin. Она охватывает только изменения вашей ветки, поэтому запускайте её до открытия pull request. Репозиторий Anthropic claude-code-security-review объясняет, как её настроить: скопируйте его security-review.md в .claude/commands/ и добавьте свои правила, например какие шаблоны в вашем коде безопасны.
Плагин security-guidance для Claude Code. Устанавливается командой /plugin install security-guidance@claude-plugins-official и проверяет код, пока Claude его пишет: проверка по шаблонам при каждой правке (вещи вроде eval(, child_process.exec, .innerHTML =), фоновая проверка безопасности diff каждого хода и более глубокая проверка, когда Claude делает коммит. Правила проекта можно добавить в .claude/claude-security-guidance.md. Документация прямо говорит, что плагин не блокирует запись и может что-то пропустить; это лишь один из слоёв.
Codex /review. Команда ревью в Codex (и codex review --uncommitted или --base main из оболочки) — это общее ревью кода. Если вам нужна именно безопасность, явно попросите сосредоточиться на ней.
Расширение security для Gemini CLI. Устанавливается командой gemini extensions install https://github.com/gemini-cli-extensions/security и добавляет /security:analyze для изменений в вашей ветке и /security:scan-deps, которая проверяет зависимости через OSV-Scanner.
Для уже существующего кода, а не изменений ветки, используйте промпты по классам из шага 2. Можно также передать агенту вывод сканеров:
Вот вывод semgrep и npm audit в файле scan-results.txt.
Для каждой находки проверь, достижима ли она из пользовательского ввода
в этом коде. Пометь каждую как подтверждённую, вероятно ложную или
требующую человека, с причиной в одну строку. Не редактируй файлы.
Шаг 4: отделите настоящие находки от ложных срабатываний
ИИ-проверки безопасности говорят одинаково уверенно, правы они или нет. Требуйте доказательств, а не вердиктов:
- Источник: где недоверенное значение попадает в систему? Тело запроса, строка запроса, загрузка файла, вебхук?
- Путь: через какие функции оно проходит до опасного вызова? Попросите цепочку с file:line для каждого шага.
- Защита: какая валидация, экранирование или авторизация стоит на этом пути и почему она не покрывает этот случай?
- Достижимость: открыт ли маршрут? Находка в заброшенном админском скрипте — не то же самое, что находка в публичном API.
Затем получите второе мнение. Новая сессия, а лучше другая модель, должна перепроверить находки высокой критичности, прежде чем кто-то начнёт писать исправление. Дайте ей находку и код, а не рассуждения первого агента, чтобы она не согласилась просто так. В статье ИИ-ревью кода описано, как оценивать находки и не давать этому циклу разрастаться.
Типичные ложные срабатывания: SQL, собранный только из констант, HTML, который проходит через автоматическое экранирование фреймворка, тестовые фикстуры с фиктивными ключами и серверные запросы на фиксированный внутренний URL. Запишите безопасные шаблоны в CLAUDE.md или AGENTS.md, чтобы последующие аудиты перестали их помечать.
Шаг 5: исправляйте с регрессионным тестом
Исправление уязвимости без теста имеет привычку возвращаться. Попросите сначала тест:
Исправь отсутствующую проверку владельца в GET /api/orders/:id (находка №2).
1. Сначала напиши тест, где пользователь A запрашивает заказ пользователя B,
и ожидай 404. Запусти его и покажи, что он падает.
2. Затем добавь проверку минимальным способом, который вписывается в наш
существующий middleware. Не меняй несвязанный код.
3. Запусти весь набор тестов и покажи мне diff.
Тест, который сначала падает, а потом проходит, доказывает, что ошибка была и что исправление её покрывает. Держите каждое исправление в отдельном коммите с понятным сообщением, чтобы история объясняла, что было не так. О привычке исправлять через тест в целом читайте в статье отладка кода с ИИ.
Та же дисциплина относится к находкам в зависимостях: обновляйте по одному пакету, запускайте тесты, читайте changelog на предмет несовместимых изменений. Массовый npm audit fix --force — верный способ превратить аудит в сбой.
Если вы нашли в репозитории настоящий секрет
Это единственный случай, где порядок шагов критичен:
- Сначала замените секрет. Отзовите ключ у провайдера и выпустите новый. Если секрет был запушен, считайте его скомпрометированным; удаление файла не отменяет утечку.
- Переместите новый секрет в менеджер секретов или окружение, а не обратно в код.
- Затем приберитесь: удалите его из кода и решите вместе с командой, переписывать ли историю. Переписывание истории не поможет, если ключ не заменён.
- Предотвратите следующий случай pre-commit-хуком. gitleaks документирует такую запись в
.pre-commit-config.yaml:
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.2
hooks:
- id: gitleaks
Пусть агент помогает с шагами 2–4, но никогда не через вставку секрета в разговор. «Ключ Stripe в src/config.ts нужно перенести в переменную окружения STRIPE_SECRET_KEY» — это всё, что ему нужно.
Сделайте проверку постоянной
Разовый аудит устаревает, как только появляется новый код. Поставьте детерминированные проверки в CI, а ИИ-ревью оставьте для pull request:
# .github/workflows/security.yml (excerpt)
- run: npm audit --audit-level=high
- run: semgrep scan --config auto --error
Для ИИ-проверки каждого pull request есть GitHub Action от Anthropic anthropics/claude-code-security-review, который оставляет находки комментариями в PR. Обязательный параметр у него claude-api-key; среди необязательных — comment-pr, exclude-directories и false-positive-filtering-instructions. Если вы уже запускаете Claude в GitHub Actions, в статье Claude Code GitHub Actions описаны настройка и работа с секретами.
Как это сделать в AgentVera
AgentVera — десктопное приложение для macOS, Windows и Linux, которое запускает Claude Code, Codex, Gemini CLI и других CLI-агентов рядом друг с другом в настоящих терминалах. Для аудитов безопасности это упрощает несколько схем:
- Workspace: поставьте аудитора только для чтения (с разрешением Ask) рядом с исправляющим агентом, который работает в worktree, и третью панель с другим CLI для второго мнения. У каждого агента свой уровень разрешений.
- Ревью кода: включите ревью в конце каждого хода в настройках проекта, и выбранная вами модель Claude проверит изменения исправляющего агента; находки приходят с критичностью и ссылкой file:line и могут вернуться к агенту, не больше двух раундов подряд.
- Review inbox: готовая работа ждёт в виде карточек, а рискованные изменения помечаются: код аутентификации и безопасности, файлы зависимостей, файлы CI и инфраструктуры,
.envи изменения без тестов. - Verify (Pro и Team): отдельный проверяющий агент только для чтения сверяет результат с критериями из вашего запроса, например «регрессионный тест существует и падает без исправления».
- Агенты в Docker: запускайте Claude Code или Codex в контейнере, который видит только папку проекта, чтобы файлы и SSH-ключи в других местах вашей машины оставались недоступны во время аудита.
- Контрольные точки: каждый ход сохраняется снимком, так что неудачное исправление отменяется одним кликом.
Сетка, worktrees, ревью кода и агенты в Docker доступны на бесплатном тарифе. Скачайте AgentVera и проведите первый аудит в отдельной ветке.
Частые ошибки
- Просить «все проблемы безопасности» разом. Получите шаблонный чек-лист. Проверяйте по одному классу.
- Исправлять до проверки. «Исправленное» ложное срабатывание добавляет код, который никто не понимает. Сначала доказательства.
- Вставлять секреты, «чтобы проверить, действуют ли они». Никогда. Вместо этого замените их.
- Запускать
npm audit fix --forceв цикле агента. Мажорные обновления ломают всё так, что поломки выглядят не связанными. - Считать чистое ИИ-ревью гарантией. Это значит лишь, что агент в этот раз ничего не нашёл. Оставьте сканеры в CI.
- Разрешать аудитору правки. Аудит — только чтение, исправления — отдельный шаг с ревью.
Подведём итог
Начните с gitleaks, аудитора зависимостей и Semgrep. Затем проверяйте по одному классу OWASP агентом в режиме только для чтения, требуя доказательств с file:line и достижимого пути. Запускайте /security-review (или аналог в вашем агенте) перед каждым pull request, пусть вторая сессия перепроверит серьёзные находки, и исправляйте каждую с регрессионным тестом, который сначала падает. Если секрет утёк, первым делом замените его. Когда будете готовы поручить агентам исправления, статья парное программирование с ИИ покажет, как оставаться в роли штурмана. Если вы только начинаете, мягче войти в тему поможет статья как научиться программировать с ИИ.