SQL injection в AI-коде появляется почти всегда по одной причине: нейросеть вставляет данные пользователя прямо в текст запроса через конкатенацию строк, а не через параметры. Дальше разберем, почему модели так делают, чем это опасно на практике и ка…
400 000+ органических переходов за 3 месяца. Со-основатель GoBanana (231K пользователей, 12+ млн ₽ без рекламы) и NeuroScribe (65K пользователей). SEO/GEO-стратегии для AI-поисковиков, 1 700+ единиц контента, 17+ реализованных стратегий.
Об авторе →Claude Code: новый CLI-агент от Anthropic
Anthropic выпустила Claude Code — терминальный AI-агент для разработчиков. Инструмент работает прямо в командной строке и умеет писать, редактировать и запускать код.
Zcode AI: Полный гид по визуальному интерфейсу для Claude Code и AI-агентов
Узнайте, как использовать Zcode для управления Claude Code, Gemini и Codex в едином GUI. Настройка провайдеров, MCP-серверов и визуальный вайбкодинг.
YouTube-канал с монетизацией из любой точки мира: Пошаговый гайд 2026
Инструкция по созданию YouTube-канала: обход блокировок SMS, настройка расширенных функций через виртуальные номера и правила безопасности для монетизации.
Windsurf Code Maps: Как глубоко понимать архитектуру проекта перед написанием кода
Полный гайд по Windsurf Code Maps, модели Sway 1.5 и Sway Grep. Узнайте, как визуализировать архитектуру кода и ускорить разработку в 13 раз.
Vk Fast Cash Strategy
Аудитория ВКонтакте — это те же люди, что и в Instagram, но 'социальный контракт' площадки другой. Если Instagram — это 'дорогой ресторан' с демонстрацией успеха, то VK — это 'душевная шашлычная'. Здесь не работает глянцевый 'успешный успех
SQL injection в AI-коде появляется почти всегда по одной причине: нейросеть вставляет данные пользователя прямо в текст запроса через конкатенацию строк, а не через параметры. Дальше разберем, почему модели так делают, чем это опасно на практике и как закрыть дыру через prepared statements или ORM на Python и Node.js. Дадим рабочие примеры кода, которые можно скопировать и адаптировать под свой проект.
Главная причина SQL injection в AI-коде: модель обучена на миллионах примеров со строковой конкатенацией и повторяет паттерн, если не указать иное. По данным Veracode за 2025 год, 45% AI-сгенерированного кода содержит хотя бы одну уязвимость. Ниже: конкретные примеры и готовые исправления.
Нейросеть предсказывает следующий токен на основе обучающих данных, а не проверяет запрос на безопасность. Строковая конкатенация встречается в старых туториалах и Stack Overflow чаще, чем prepared statements, поэтому модель выдает именно ее.

Языковая модель не "думает" о безопасности базы данных. Она продолжает текст так, как чаще всего продолжали похожий код авторы обучающей выборки. А выборка забита старыми туториалами, где f"SELECT * FROM users WHERE id = {user_id}" выглядит короче и понятнее для новичка, чем параметризованная версия.
Здесь есть нюанс. Исследование Pearce и коллег по коду GitHub Copilot нашло уязвимости примерно в 40% из 1 689 проверенных программ, причем в Python доля составила около 39%. SQL injection входит в число самых частых категорий наравне с XSS и утечкой credentials в этих же тестах.
Проблема усиливается тем, что модель не знает контекста вашей архитектуры. Она не в курсе, что это поле формы примет ввод от анонимного пользователя из интернета, а не от доверенного администратора. Отсюда и совет: любой AI-сгенерированный SQL-запрос стоит читать так, будто его написал стажер в первый рабочий день.
Уязвимый код обычно строит запрос через f-строку, + или шаблонный литерал, вставляя ввод пользователя напрямую в текст SQL. Безопасный код передает данные отдельным параметром, а не частью строки запроса.
Возьмем классический пример на Python. AI-ассистент на запрос "напиши функцию поиска пользователя по имени" часто выдает такое:
def get_user(username):
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)
return cursor.fetchone()Выглядит рабочим на тестах. Но если в поле username прилетит ' OR '1'='1, итоговый запрос превратится в SELECT * FROM users WHERE username = '' OR '1'='1', и база вернет первую попавшуюся запись, часто администратора. Ровно такую логику "пароль или 1=1" разбирает и разбор SQL injection на YouTube-канале про базы данных: злоумышленник просто говорит системе "впусти меня в любом случае", а код буквально выполняет инструкцию.

На Node.js паттерн идентичный, только конкатенация идет через шаблонные литералы:
const query = `SELECT * FROM users WHERE username = '${username}'`;
connection.query(query, callback);Оба примера пройдут код-ревью, если ревьюер не читает SQL-строку внимательно. Именно поэтому уязвимость живет в проде месяцами.
SQL injection дает доступ к чужим данным, обходу авторизации и иногда к полному контролю над сервером. Это не теоретический риск: OWASP тестирует инъекции в 100% приложений, а на SQL injection приходится больше 14 000 зарегистрированных CVE.
Диапазон последствий широкий. Минимум — злоумышленник читает чужие данные через UNION-based инъекцию, буквально "сшивая" результат из разных таблиц в один ответ. Максимум — получает права администратора через обход логина, удаляет таблицы или вызывает команды операционной системы, если СУБД это позволяет.
В новой версии OWASP Top 10:2025 категория Injection опустилась с третьего на пятое место, но осталась одной из самых проверяемых: тестирование проходит 100% приложений, а количество CVE для нее выше, чем у любой другой категории. Отдельно по SQL injection зафиксировано больше 14 000 CVE (owasp.org).
Для AI-кода статистика хуже среднего. По отчету Veracode за 2025 год генеративные модели вносят уязвимость примерно в 45% случаев, а для Java этот показатель превышает 70% (ardura.consulting). SQL injection через конкатенацию строк входит в тройку самых частых категорий сразу после XSS и Log Injection.
Максим: «GoBanana мы собрали за 3 часа после выхода модели, и это реально работает как продукт. Но именно на такой скорости чаще всего проскакивает SQL injection: код рабочий, тесты зеленые, а запрос к базе собран конкатенацией. После любого AI-кода с базой данных я отдельным промптом прошу проверить запросы на инъекции.»

Prepared statement отделяет структуру SQL-запроса от данных пользователя: вместо вставки строки в текст запроса подставляется плейсхолдер, который база данных обрабатывает как обычные данные, а не как код.
Для sqlite3 и psycopg2 синтаксис почти одинаковый, разница только в символе плейсхолдера. Вот безопасная версия функции из предыдущего примера:
def get_user(username):
query = "SELECT * FROM users WHERE username = ?"
cursor.execute(query, (username,))
return cursor.fetchone()Для PostgreSQL через psycopg2 плейсхолдер меняется на %s, логика та же:
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))Ключевой момент: база данных сначала компилирует план запроса с плейсхолдером на месте значения, и только потом подставляет данные. Даже если в username прилетит ' OR '1'='1, СУБД воспримет это как обычную строку для сравнения, а не как часть SQL-синтаксиса. Именно это разделение структуры и данных лежит в основе всех современных методов защиты от инъекций.

Если промпт для AI-ассистента звучит как "напиши функцию поиска пользователя", просите сразу указывать в промпте "через prepared statements, без f-строк". Разница в одной фразе промпта часто решает всю проблему.
В Node.js с MySQL или PostgreSQL параметризация делается через знаки вопроса или пронумерованные плейсхолдеры, а не через шаблонные литералы с подстановкой значений.
Для пакета mysql2 безопасная версия выглядит так:
connection.execute(
'SELECT * FROM users WHERE username = ?',
[username],
(err, results) => {
if (err) throw err;
callback(results);
}
);Для PostgreSQL через pg плейсхолдеры нумеруются, а порядок параметров в массиве должен строго совпадать с порядком знаков в запросе:
const result = await pool.query(
'SELECT * FROM users WHERE username = $1 AND status = $2',
[username, status]
);Один нюанс из практики: если параметров несколько, легко перепутать их порядок при рефакторинге. Добавляйте комментарий рядом со списком параметров, если запрос длинный. Стоит также проверить, не включена ли в конфигурации MySQL опция multipleStatements: true. Она разрешает выполнение нескольких SQL-команд через точку с запятой в одном вызове и обнуляет часть защиты prepared statements, если разработчик забыл ее выключить после отладки.
ORM использует prepared statements внутри себя, поэтому обе технологии не конкурируют, а решают одну задачу на разных уровнях абстракции. Для новых проектов проще начать с ORM, для точечных исправлений в legacy-коде быстрее prepared statements.
Разработчики ORM-библиотек вроде Prisma, SQLAlchemy или Sequelize построили абстракцию поверх параметризованных запросов: вы вызываете метод объекта, а библиотека сама собирает безопасный SQL под капотом. Так параметризация становится побочным эффектом, а не отдельной задачей, о которой нужно помнить каждый раз.

| Критерий | Prepared statements напрямую | ORM (Prisma, SQLAlchemy, Sequelize) |
|---|---|---|
| Скорость внедрения в новый код | Быстро, но легко забыть на одном из запросов | Защита включена по умолчанию для стандартных операций |
| Контроль над запросом | Полный, видно каждую строку SQL | Часть контроля скрыта в абстракции |
| Порог входа для новичка | Нужно помнить синтаксис плейсхолдеров под конкретную СУБД | Методы вида findFirst, where читаются проще |
| Риск при "сыром" SQL-запросе | Защита работает только там, где применена вручную | Часто есть режим raw query, который снова открывает риск инъекции |
| Производительность на сложных запросах | Максимальный контроль над оптимизацией | Иногда генерирует избыточный SQL под капотом |
Важная оговорка: даже в ORM остается лазейка. Почти в каждой библиотеке есть метод для "сырого" SQL-запроса на случай сложной аналитики, и если в него вставить данные пользователя через конкатенацию, ORM не спасет. Механизм защиты одинаковый что в prepared statements, что в ORM: разделение SQL-кода и данных на два разных канала.
Prepared statements закрывают основной вектор атаки, но не единственный. Ограничение прав доступа к базе, скрытие текста ошибок и регулярное тестирование добавляют второй и третий уровень защиты.
Раз — ограничьте права пользователя базы данных, от имени которого работает приложение. Учетная запись для веб-сервера не должна иметь права DROP TABLE или доступ к системным таблицам, даже если инъекция каким-то образом обойдет параметризацию.
Два — скрывайте технические сообщения об ошибках от конечного пользователя. Текст ошибки СУБД часто раскрывает структуру таблиц и версию базы, а это готовая шпаргалка для атакующего при error-based инъекции.
Три — проверяйте формат входных данных до того, как они попадут в запрос. Если поле ожидает число, а пришла строка с кавычками, это повод отклонить запрос еще до обращения к базе.
Плюс регулярное тестирование инструментами вроде SQLMap или OWASP ZAP до релиза, а не после инцидента. Отсутствие ошибок в логах не означает отсутствие уязвимости: слепые (blind) инъекции вообще не выдают прямых сообщений об ошибке, а извлекают данные через задержку ответа или логику true/false.

Перед тем как принять предложенный ассистентом код с обращением к базе, пройдитесь по короткому чек-листу. Ищите конкатенацию через f-строки, + или шаблонные литералы рядом с переменной пользователя. Проверьте, что запрос использует плейсхолдеры, а не готовую строку. Убедитесь, что учетная запись базы данных не работает с правами администратора. Отдельно проверьте raw-запросы внутри ORM, если они есть в проекте.

Какой бы AI-редактор вы ни использовали, привычка перечитывать SQL-запрос строку за строкой должна остаться на вас. Инструменты вроде Cursor, Claude Code или GitHub Copilot ускоряют написание кода, но не несут ответственности за архитектуру безопасности вашего проекта. Разница между уязвимым и защищенным запросом часто в одной фразе промпта: "используй prepared statements, не строй запрос через конкатенацию строк".
Если вы работаете в связке маркетолог плюс вайбкодинг и часто закрываете задачи devops или безопасности вручную, в каталоге агентов VibeCoderz есть готовый агент под эту нишу: агент для devops-задач.
SQL injection — атака, при которой данные пользователя интерпретируются базой как часть SQL-кода, а не как обычное значение.
Prepared statement (подготовленное выражение) — SQL-запрос с плейсхолдерами вместо значений, где данные подставляются отдельно от текста запроса на уровне драйвера базы.
ORM (Object-Relational Mapping) — библиотека, которая позволяет работать с базой данных через объекты и методы кода вместо написания SQL вручную.
Конкатенация строк — склеивание текста запроса и данных пользователя в одну строку через +, f-строку или шаблонный литерал. Основная причина SQL injection.
Blind SQL injection — вид атаки, где злоумышленник не видит данные напрямую, а определяет их по поведению приложения: ответ true/false или задержка загрузки страницы.
CWE-89 — код категории "SQL Injection" в классификаторе Common Weakness Enumeration, используется в отчетах о безопасности кода.
Least privilege (принцип минимальных прав) — правило, по которому учетная запись базы данных получает только те права, которые реально нужны приложению.
Может ли Claude или GPT сам написать безопасный SQL-запрос без напоминаний? Иногда да, если в промпте прямо указана безопасность. Без явного указания модель чаще выдает конкатенацию строк, потому что такой паттерн чаще встречается в обучающих данных.
Достаточно ли ORM, чтобы полностью забыть про SQL injection? Нет. ORM закрывает стандартные операции, но почти в каждой библиотеке есть режим raw SQL для сложных запросов, и там риск инъекции возвращается, если данные вставлены через конкатенацию.
Как быстро проверить проект на SQL injection, если код уже в проде? Прогоните эндпоинты через SQLMap или OWASP ZAP на тестовом окружении, поищите в коде конкатенацию рядом с переменными пользователя и вручную проверьте формы логина и поиска.
Нужны ли prepared statements, если база доступна только внутри локальной сети? Да. Внутренняя сеть не защищает от инсайдера, скомпрометированного сервиса или ошибки в другом эндпоинте, через который атакующий доберется до внутреннего API.
Чем отличается SQL injection от prompt injection в AI-агентах? SQL injection атакует базу данных через конкатенацию строк в запросе. Prompt injection атакует саму AI-модель, подсовывая скрытые инструкции в тексте, который она обрабатывает. Механизм разный, но суть одна: система выполняет чужую команду, приняв ее за обычные данные.
Скрывает ли HTTPS от SQL injection? Нет. HTTPS шифрует канал передачи данных, но не проверяет содержимое запроса. Инъекция происходит на уровне обработки данных на сервере, а не на уровне транспорта.
Что делать, если AI-ассистент постоянно предлагает конкатенацию несмотря на просьбы? Добавьте в системный промпт или кастомные правила проекта явное требование использовать prepared statements или ORM-методы, и попросите модель объяснить выбор перед выдачей кода с обращением к базе.
Если нужно быстро провести аудит существующего AI-кода на такие уязвимости или выстроить процесс код-ревью под вайбкодинг, посмотрите каталог инструментов VibeCoderz на странице каталог AI IDE или запишитесь на консультацию к Максиму: t.me/maxnagovitsyn.
Обновлено: июль 2026.