SQL-инъекция — это когда текст, который вы ввели в поле поиска, становится «частью команды» для базы данных. Вот как она работает и как её надёжно предотвратить (без шагов атаки).
Почему это происходит (механизм)
Корневая причина — построение SQL склейкой строк. Подмешайте ввод прямо в выражение, и он может пересечь «границу значения» и сработать как команда.
✗ Склейка строк (опасно)
Ввод склеен в выражение → ввод может быть прочитан как часть команды
✓ Плейсхолдеры (безопасно)
Значения передаются в слоты ? / $1 как данные → всегда остаются значениями
Ущерб — «всё, что может это соединение с БД». Если внутренняя БД достижима, это классическая причина массовых утечек, наряду с RCE и SSRF.
Защита
Используйте плейсхолдеры / подготовленные выражения (самое важное)
Не стройте SQL склейкой. Передавайте значения через ? / именованные параметры как «данные». Уже это почти полностью устраняет весь класс.
Опирайтесь на ORM / конструктор запросов
Большинство ORM используют плейсхолдеры по умолчанию. Чем меньше сырого SQL вы пишете руками, тем безопаснее. Если приходится писать сырой SQL, всегда параметризуйте его.
Пользователь БД с минимумом привилегий
Не давайте пользователю БД приложения лишних прав (DROP, другие таблицы, админ-операции). Даже при взломе локализуйте ущерб.
Валидация ввода как дополнение
Проверки типа/длины/формата помогают, но не делайте их основной защитой; они лишь дополняют плейсхолдеры.
Мнение этого сайта: перестаньте вообще строить сырой SQL руками
SQLi известна очень давно, но всё ещё встречается, потому что подмешивать ввод в выражение «удобно». Позиция этого сайта проста: никогда не создавайте место, где значения склеиваются строками в SQL. Сделайте плейсхолдеры или ORM умолчанием, и эта уязвимость предотвращается самой архитектурой. Не полагайтесь на ручное экранирование.
Осторожно: плейсхолдеры несут только значения
Плейсхолдеры покрывают не всё. Они несут только значения — не структуру запроса вроде имён таблиц, имён столбцов или направления ORDER BY (asc/desc).
Когда они нужны динамическими (например, дать пользователю выбрать «ключ сортировки» или «столбец фильтра»), не вставляйте ввод в SQL — выбирайте реальное имя из заранее заданного allowlist. «Столбец сортировки» и «столбец фильтра» — классические слепые пятна, где люди полагают, что плейсхолдеры их прикрыли.
Ввод — это не только поля форм
Если считать, что осторожность нужна только с полями поиска и формами входа, случаи будут упущены. Значения, которые могут попасть в SQL, приходят многими путями.
- HTTP-заголовки (
User-Agent,X-Forwarded-Forи т. д.) и cookie - Значения в JSON, полученном API, или прочитанные из файлов
- Значения, однажды сохранённые в базу данных и позже встроенные в SQL другим процессом
Последнее называется SQL-инъекцией второго порядка. Даже если при сохранении вы использовали плейсхолдеры, она срабатывает, когда другой процесс позже склеивает сохранённое значение строкой. Не думайте «это пришло из моей собственной базы данных, значит безопасно»: используйте плейсхолдеры везде, где собирается SQL.
В разборе этого сайта о подделке X-Forwarded-For описан случай, когда пробные строки приходили в заголовке, но SQL-инъекция не сработала, потому что значение передавалось через плейсхолдер.
Чем отличается от похожих терминов
У уязвимостей с «инъекцией» в названии есть общее: ввод читается как команды на другом языке. Разница в том, куда попадает ввод.
| Термин | Куда попадает ввод | Основной ущерб | Коренное исправление |
|---|---|---|---|
| SQL-инъекция | Команды к базе данных (SQL) | Чтение, изменение или удаление данных | Плейсхолдеры |
| XSS | HTML или JavaScript, выполняемые в браузере пользователя | Злоупотребление сессией пользователя, поддельное содержимое на странице | Экранирование при выводе и CSP |
| Инъекция команд ОС | Команды, выполняемые оболочкой сервера | Выполнение любой команды на сервере (RCE) | Использовать API без оболочки и передавать аргументы отдельно |
SQL-инъекцию и XSS часто упоминают вместе, но ущерб приходится на разные места: SQL-инъекция бьёт по базе данных на сервере, XSS — по браузеру пользователя.
Как называются плейсхолдеры в основных языках
Каждый основной язык даёт способ передавать значения отдельно. Используйте это как подсказку, какую функцию применять в своём стеке.
| Язык / библиотека | Что использовать |
|---|---|
| Java (JDBC) | PreparedStatement с методами задания значений вроде setString |
| PHP (PDO) | Подготовить выражение через prepare, передать значения в execute |
| Python (DB-API) | Передавать значения вторым аргументом execute (не встраивать их в строку SQL) |
| Node.js (pg и другие) | Нумерованные символы вроде $1, а значения — отдельным массивом |
| C# (.NET) | Добавлять значения в Parameters команды |
В любом языке, как только вы встраиваете значения в SQL через шаблонные строки или +, эта защита перестаёт работать.
Реальные примеры: крупные утечки, начавшиеся с SQL-инъекции в продукте
SQL-инъекция известна давно, но до сих пор приводит к крупным утечкам. Недавние случаи часто начинались не в собственном коде, а в используемом продукте.
| Случай | Что произошло |
|---|---|
| MOVEit Transfer (2023) | SQL-инъекцию в продукте для передачи файлов (CVE-2023-34362) эксплуатировали до выхода исправления, и были похищены данные более 2700 организаций, многих — через их подрядчиков (→ массовая утечка через MOVEit) |
| Metabase (2026) | SQL-инъекцию без аутентификации в инструменте аналитики (CVE-2026-72898) эксплуатировали до исправления, и несколько компаний сообщили об утечке данных клиентов (→ эксплуатация Metabase и утечки, на английском) |
| Ядро WordPress (2026) | В сочетании с другой уязвимостью SQL-инъекция без аутентификации могла привести к RCE (→ разбор CVE-2026-63030, на английском) |
После MOVEit американские CISA и ФБР в марте 2024 года выпустили предупреждение с призывом к производителям ПО устранить SQL-инъекции, назвав решением параметризованные запросы (плейсхолдеры). В «CWE Top 25» MITRE, опубликованном в декабре 2025 года, SQL-инъекция (CWE-89) стоит на втором месте.
Что делать — зависит от вашей роли
| Ваша роль | Что сделать в первую очередь |
|---|---|
| Вы пишете SQL (разработчик) | Перестаньте склеивать строки; используйте плейсхолдеры или ORM. Проверьте, как используются функции для сырого SQL |
| Вы эксплуатируете продукты или open source (администратор) | Проверьте CVE и статус KEV используемых продуктов и обновитесь до исправленных версий. Сократите число админ-панелей, доступных из интернета |
| Обе роли | Дайте пользователю БД приложения минимум привилегий — только нужные таблицы и столбцы |
Как проверить своё окружение
Чтобы это проверить, вводить строки атаки не нужно. Всё необходимое скажут код и настройки.
Найдите SQL, собранный из строк
Поищите в коде строки, где ключевые слова SQL (SELECT, WHERE и т. п.) соседствуют со склейкой строк или шаблонными строками. Проверьте также, что ввод не склеивается в функции для сырого SQL ($queryRawUnsafe, whereRaw, DB::raw, raw() и подобные).
Запишите, что может пользователь БД
Проверьте, к каким таблицам у пользователя БД приложения есть доступ и что он может с ними делать (SHOW GRANTS в MySQL, information_schema.role_table_grants в PostgreSQL). Уберите ненужные права на удаление и доступ к таблицам других приложений.
Сверьте используемые продукты с данными об уязвимостях
С помощью «Поиска CVE / KEV» посмотрите известные уязвимости в используемых продуктах и то, эксплуатируются ли они. Зависимости все сразу проверит osv-scanner.
Убедитесь, что ошибки SQL не показываются на экране
В продакшене проверьте, что сообщения об ошибках базы данных не показываются пользователям как есть. Подробные ошибки держите только в логах.
Ищите признаки в логах
Проверьте, не выросло ли внезапно число синтаксических ошибок базы данных и не видно ли в логах WAF или доступа серии запросов с одного источника, содержащих похожие на SQL строки. Если да, в первую очередь проверьте код, стоящий за этим маршрутом.
Источники (первичные)
- OWASP, «SQL Injection Prevention Cheat Sheet» — cheatsheetseries.owasp.org (плейсхолдеры, предостережения о хранимых процедурах, проверка ввода по allowlist, минимум привилегий, отказ от опоры на экранирование)
- CISA и ФБР, «Secure by Design Alert: Eliminating SQL Injection Vulnerabilities in Software» (25 марта 2024 г.) — cisa.gov
- MITRE, «2025 CWE Top 25 Most Dangerous Software Weaknesses» (декабрь 2025 г.) — cwe.mitre.org (CWE-89 на втором месте)
- IPA, «How to Secure Your Web Site» — ipa.go.jp (на японском; коренные решения и смягчающие меры)
Читать дальше
- Глоссарий: Что такое RCE · Что такое XSS · Что такое OWASP Top 10
- Разбор: Подделка X-Forwarded-For и настройки доверенного прокси
- Основы: Основы безопасности