Как найти уязвимости в коде с помощью ИИ

Аудит своего кода с AI-агентом: классы OWASP, поиск секретов и уязвимых зависимостей, /security-review, ложные срабатывания и исправления с тестом.

Solviera Teknoloji 10 мин чтения

Чтобы найти уязвимости в своём коде с помощью ИИ, сначала запустите быстрые детерминированные сканеры (секреты, зависимости, статические правила), а затем давайте агенту для программирования по одному классу уязвимостей и просите проследить, как недоверенные данные проходят через ваш код. Считайте каждую находку утверждением, которое нужно проверить, исправляйте её с регрессионным тестом и всё это время держите агента подальше от настоящих секретов.

Это руководство — об аудите вашего собственного кода, с позиции защиты. Если вы хотите узнать, как не дать навредить самому агенту (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 — верный способ превратить аудит в сбой.

Если вы нашли в репозитории настоящий секрет

Это единственный случай, где порядок шагов критичен:

  1. Сначала замените секрет. Отзовите ключ у провайдера и выпустите новый. Если секрет был запушен, считайте его скомпрометированным; удаление файла не отменяет утечку.
  2. Переместите новый секрет в менеджер секретов или окружение, а не обратно в код.
  3. Затем приберитесь: удалите его из кода и решите вместе с командой, переписывать ли историю. Переписывание истории не поможет, если ключ не заменён.
  4. Предотвратите следующий случай 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, пусть вторая сессия перепроверит серьёзные находки, и исправляйте каждую с регрессионным тестом, который сначала падает. Если секрет утёк, первым делом замените его. Когда будете готовы поручить агентам исправления, статья парное программирование с ИИ покажет, как оставаться в роли штурмана. Если вы только начинаете, мягче войти в тему поможет статья как научиться программировать с ИИ.

Вопросы

Может ли AI-агент для программирования находить уязвимости?

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

Что делает /security-review в Claude Code?

Команда анализирует изменения в вашей текущей ветке на уязвимости, сравнивая их с веткой по умолчанию удалённого репозитория origin, и сообщает о рисках вроде инъекций, проблем с аутентификацией и утечки данных. Ей нужен remote origin. Она проверяет diff, а не весь репозиторий.

Стоит ли дать агенту мой .env, чтобы он проверил секреты?

Нет. Никогда не вставляйте настоящие секреты в промпт. Ищите их сканером секретов вроде gitleaks, не давайте агенту читать .env, а если настоящий ключ когда-либо попал в коммит, сначала замените его и только потом чистите историю.

Что делать с ложными срабатываниями ИИ-проверки безопасности?

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

Заменяет ли ИИ-аудит безопасности тест на проникновение?

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

Соберите своих агентов за одним столом.

Скачайте AgentVera бесплатно; ваши установленные CLI уже готовы к работе.

Другие статьи