Написать нам в Telegram

Что такое SQL-инъекция и как защитить от неё сайт

Безопасность
19 сентября 2026 г.
Фото Максим Козлов
Максим КозловРуководитель отдела разработки

SQL-инъекция — это атака на сайт, при которой злоумышленник подсовывает в форму, адресную строку или cookie фрагмент SQL-кода, а сайт выполняет его в базе данных как собственную команду. В результате посторонний человек может прочитать таблицу клиентов, войти в админку без пароля или стереть заказы. Если коротко, SQL-инъекции — это следствие одной ошибки разработчика: пользовательские данные склеиваются с текстом запроса. Ниже разберём, что такое SQL-инъекция на простом примере, какие бывают виды, чем утечка базы грозит бизнесу по 152-ФЗ, как проверить свой сайт и как защититься. Статья для владельца сайта и его разработчика: владельцу хватит текста и таблиц, разработчику пригодятся примеры кода.

Что такое SQL-инъекция простыми словами

Почти любой сайт с каталогом, личным кабинетом или формой заявки хранит данные в базе: MySQL, PostgreSQL, MS SQL. Сайт общается с базой на языке SQL: «найди товар с id 15», «проверь логин и пароль», «сохрани заказ». Часть такого запроса берётся из того, что прислал посетитель: номер товара из ссылки, текст из поиска, логин из формы входа.

Представьте бланк, в котором сотрудник вписывает фамилию клиента в готовую фразу «Выдать справку клиенту ___» и не глядя передаёт в архив. Если клиент впишет вместо фамилии «Иванову, а также выдать все личные дела», архив выполнит и вторую часть. SQL-инъекция работает так же: база не отличает, где заканчиваются данные посетителя и начинается команда программиста, потому что всё пришло одной строкой.

Корень SQL-инъекции не в «хитрых хакерах», а в архитектуре кода: запрос собирается склейкой строк. Пока данные и команда передаются в базу раздельно, внедрить команду через поле ввода невозможно.

Как работает SQL-инъекция: пример уязвимого и исправленного кода

Разберём учебный пример на PHP — языке, на котором написаны WordPress и 1С-Битрикс. Он показывает сам механизм, а не приём атаки на конкретный сайт.

Уязвимый запрос: склейка строк

// Карточка товара: /product.php?id=15
$id = $_GET['id'];
$sql = "SELECT name, price FROM products WHERE id = " . $id;
$result = $db->query($sql);

Пока в ссылке число, всё работает. Но значение id целиком контролирует посетитель. Если вместо «15» передать «15 OR 1=1», база получит запрос WHERE id = 15 OR 1=1, условие станет истинным для всех строк, и страница выдаст весь каталог. Это безобидная демонстрация, но тем же путём в запрос можно дописать чтение другой таблицы, например пользователей с хешами паролей. Классический пример с формой входа — ввод ' OR '1'='1 в поле пароля: если проверка собрана склейкой, условие «пароль совпал» всегда истинно.

Исправленный запрос: PDO и prepared statements

$pdo = new PDO($dsn, $user, $pass, [
	PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
	PDO::ATTR_EMULATE_PREPARES => false,
]);

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
	http_response_code(404);
	exit;
}

$stmt = $pdo->prepare('SELECT name, price FROM products WHERE id = :id');
$stmt->execute(['id' => $id]);
$product = $stmt->fetch();

Здесь текст запроса отправляется в базу отдельно от значения. База сначала разбирает шаблон с меткой :id, а потом подставляет данные строго как значение. Что бы ни пришло в параметре, командой оно уже не станет. Дополнительно число проверяется на входе: мусор отсекается ещё до обращения к базе.

Параметром нельзя передать имя столбца или таблицы, например поле сортировки в ORDER BY. Для таких мест используйте белый список: сравнивайте значение с перечнем разрешённых столбцов и подставляйте только значение из этого перечня.

Виды SQL-инъекций: классическая, слепая, time-based, second-order

Типы SQL-инъекций различаются тем, как атакующий получает результат. Для владельца важно одно: «невидимые» виды не безопаснее видимых, просто данные вытягиваются медленнее.

ВидКак работаетЧем опаснаКак заметить
Классическая (in-band: UNION, error-based)Результат чужого запроса выводится прямо на страницу или в текст ошибки базыБыстрое выкачивание таблиц целикомОшибки SQL на страницах, странные параметры в логах
Слепая (boolean-based)Страница не показывает данные, но меняется в зависимости от того, истинно ли условие. Данные вытягиваются по одному битуРаботает даже при скрытых ошибкахТысячи однотипных запросов к одному адресу
По времени (time-based)Атакующий заставляет базу «задуматься» на несколько секунд, если условие верно, и судит по задержке ответаОбходит сайты, где ответ всегда одинаковыйВсплески медленных запросов, нагрузка на базу
Отложенная (second-order)Вредная строка сначала безопасно сохраняется, например в имени профиля, а срабатывает позже, когда другой участок кода вставляет её в запрос склейкойПроходит мимо проверки форм и простых сканеровТолько анализ кода
Внеполосная (out-of-band)База сама отправляет данные на внешний сервер атакующего, например через DNS-запросРедкая, зависит от настроек СУБДИсходящие соединения с сервера базы

Чем SQL-инъекция опасна для бизнеса

Одна уязвимая строка кода даёт доступ ко всей базе, с которой работает сайт. На практике это означает:

  • Утечку клиентской базы: ФИО, телефоны, адреса доставки, история заказов. Такие дампы продаются и потом используются для мошеннических звонков от имени вашей компании.
  • Захват админки: из таблицы пользователей достаются логины и хеши паролей, слабые хеши подбираются, дальше меняются реквизиты оплаты, подкладываются вредоносные скрипты.
  • Порчу и удаление данных: изменённые цены, стёртые заказы, подменённые страницы.
  • Плацдарм для дальнейшего взлома: при лишних правах у пользователя базы можно записать файл на сервер и получить полноценный доступ к хостингу.

Утечка через SQL-инъекцию и 152-ФЗ

Если через уязвимость утекли персональные данные, отвечает оператор, то есть владелец сайта, а не хакер. По 152-ФЗ о неправомерной передаче персональных данных нужно уведомить Роскомнадзор дважды: в течение 24 часов с момента выявления — о самом инциденте, предполагаемых причинах и принятых мерах, в течение 72 часов — о результатах внутреннего расследования и виновных, если они установлены. С 30 мая 2025 года действуют повышенные штрафы по ст. 13.11 КоАП РФ для компаний и ИП:

НарушениеШтраф для компании / ИП
Не уведомили Роскомнадзор об утечке1–3 млн ₽
Утечка данных 1 000–10 000 человек3–5 млн ₽
Утечка данных 10 000–100 000 человек5–10 млн ₽
Утечка данных более 100 000 человек10–15 млн ₽
Утечка специальных категорий данных10–15 млн ₽
Утечка биометрических данных15–20 млн ₽
Повторная утечка1–3% годовой выручки, но не меньше 20 млн ₽ (для специальных категорий и биометрии — 25 млн ₽) и не больше 500 млн ₽
Оборотный штраф назначается за повторную утечку. Если сайт уже взламывали и дыру «залатали» удалением вируса, не найдя уязвимость в коде, второй инцидент обойдётся в разы дороже первого.

Где чаще всего встречаются SQL-инъекции

Современные фреймворки и ядра популярных CMS по умолчанию защищены: в Laravel, Symfony, Django, Prisma и ORM 1С-Битрикс (D7) запросы строятся с параметрами. Инъекции появляются там, где разработчик обошёл эти механизмы или их не было:

  • Самописные сайты 2000-х и 2010-х на «голом» PHP с устаревшим расширением mysql_* и ручной склейкой запросов.
  • Плагины и модули сторонних авторов для WordPress, Битрикс, OpenCart. Уязвимости в ядре редки, в дополнениях их находят регулярно, а обновления ставят не все.
  • Легаси-доработки: фильтры каталога, выгрузки, отчёты, интеграции с 1С, написанные на скорую руку в обход ORM, например через $wpdb->query() без $wpdb->prepare() или $DB->Query() в Битрикс без экранирования.
  • Сырые запросы внутри ORM: DB::raw(), $queryRawUnsafe и аналоги, куда подставлен ввод пользователя.
  • Сортировка, поиск и фильтры: параметры вроде sort=price или order=desc, которые нельзя передать параметром и которые часто вставляют как есть.

Если сайт делали несколько подрядчиков и никто не знает, что лежит в коде, риск выше среднего. Об общих угрозах для сайтов бизнеса подробнее в статье о кибербезопасности сайта в 2026 году.

SQL-инъекция в OWASP Top 10 2025

OWASP Top 10 — самый известный рейтинг рисков веб-приложений, на него ссылаются аудиторы, банки-эквайеры и требования к разработке. В редакции 2025 года категория Injection занимает пятое место (A05:2025). В 2017 году она была первой, в 2021-м — третьей. Снижение говорит не о том, что проблема ушла, а о том, что фреймворки с параметризованными запросами стали нормой.

При этом по данным OWASP на инъекции проверяли 100% протестированных приложений, а у категории больше всего известных уязвимостей (CVE): свыше 14 тысяч приходится именно на SQL-инъекции. Для старого кода и сторонних модулей это по-прежнему одна из самых реальных угроз.

Как проверить сайт на SQL-инъекции

Самостоятельно владелец может проверить косвенные признаки, а полноценная проверка — работа специалиста. Методы дополняют друг друга:

  1. Анализ исходного кода (ручной и SAST). Поиск мест, где ввод пользователя попадает в запрос склейкой. Единственный способ найти second-order инъекции и уязвимости на закрытых страницах.
  2. Динамическое сканирование (DAST). OWASP ZAP, Burp Suite и аналоги отправляют тестовые данные в формы и параметры и анализируют ответы. Находят очевидное, дают ложные срабатывания, которые нужно проверять вручную.
  3. Специализированные инструменты вроде sqlmap. Подтверждают, эксплуатируется ли уязвимость. Запускать их можно только на своём сайте или с письменного разрешения владельца, лучше на копии: тесты создают нагрузку и могут изменить данные. Атака на чужой сайт, даже «проверочная», может быть квалифицирована как неправомерный доступ к компьютерной информации (ст. 272 УК РФ).
  4. Логи веб-сервера и WAF. Параметры с кавычками, словами UNION, SELECT, SLEEP, тысячи запросов к одной странице с одного адреса — признак, что вас уже пробуют.
  5. Проверка версий CMS и модулей по базам известных уязвимостей: если у установленной версии плагина есть опубликованная SQL-инъекция, её найдут автоматические боты раньше вас.

Базовую самопроверку сайта без инструментов пентестера можно пройти по чек-листу из 15 пунктов. Если нужен полный разбор кода, конфигурации и прав с отчётом по критичности, это задача для аудита безопасности сайта.

Как защититься от SQL-инъекций

Методы защиты работают слоями. Первый пункт закрывает саму уязвимость, остальные снижают ущерб, если где-то осталась ошибка.

  1. Параметризованные запросы или ORM везде. PDO и mysqli с prepared statements в PHP, $wpdb->prepare() в WordPress, ORM D7 в Битрикс, query builder в Laravel, параметры в node-postgres и mysql2. Сырой SQL со склейкой — только с обоснованием на код-ревью.
  2. Белые списки для идентификаторов. Имена столбцов, направление сортировки, названия таблиц выбираются из заранее заданного перечня.
  3. Валидация входных данных. Число должно быть числом, дата — датой, длина строки ограничена. Это не замена параметрам, а второй барьер.
  4. Минимальные права пользователя базы. Сайту не нужны права на удаление таблиц, запись файлов (FILE в MySQL) и доступ к чужим базам. Отдельные учётки для сайта, админки и выгрузок.
  5. Скрытие ошибок на продакшене. Текст ошибок SQL пишется в лог, посетитель видит нейтральную страницу. Это не устраняет уязвимость, но лишает атакующего подсказок.
  6. WAF. Веб-фаервол на уровне хостинга, nginx (ModSecurity) или облачного сервиса блокирует типовые шаблоны атак и выигрывает время до исправления кода.
  7. Обновления и контроль зависимостей. Ядро CMS, плагины, модули, пакеты npm и Composer обновляются регулярно, заброшенные расширения заменяются.
  8. Надёжное хранение паролей и бэкапы. Пароли только в виде хешей bcrypt или Argon2, резервные копии базы вне сервера сайта.
Попросите разработчика поискать в коде все вызовы запросов к базе и показать, где в них попадает переменная без параметра. Для небольшого сайта это несколько часов работы, и результат сразу покажет масштаб проблемы.

Типичные ошибки в защите от SQL-инъекций

  • Ручное экранирование вместо параметров. addslashes() и самописные функции чистки ломаются на кодировках и числовых параметрах без кавычек.
  • Чёрный список слов. Фильтр, вырезающий SELECT и UNION, обходится сменой регистра, комментариями и кодированием.
  • Ставка только на WAF. Фаервол не видит отложенные инъекции и пропускает нестандартные обходы. Это страховка, а не лечение.
  • Проверка только в браузере. JavaScript-валидация формы отключается за секунду, запрос можно отправить напрямую.
  • Защищены формы, но не API и выгрузки. Мобильное приложение, обмен с 1С и внутренние отчёты тоже принимают данные.

Что делать, если сайт взломали через SQL-инъекцию

  1. Сохраните логи веб-сервера, базы и WAF за последние недели до любых чисток: без них не установить, что и когда утекло.
  2. Закройте вход: отключите уязвимый раздел или временно переведите сайт в режим обслуживания, смените пароли к базе, админке, FTP и SSH, ключи API.
  3. Оцените, были ли затронуты персональные данные. Если да — уведомление в Роскомнадзор в течение 24 часов, результаты расследования в течение 72 часов.
  4. Найдите и исправьте уязвимый код, а не только удалите последствия. Проверьте, не оставлены ли на сервере веб-шеллы и новые учётки администраторов.
  5. Проверьте целостность данных: цены, реквизиты оплаты, настройки почты, содержимое страниц.
  6. Перепроверьте весь код на похожие места: где нашлась одна склейка, почти всегда есть ещё.

Пошаговый разбор первых часов после инцидента есть в статье «Взломали сайт на Битрикс: что делать прямо сейчас», он подходит и для других CMS. Если сайт заражён, заблокирован или работает с ошибками, начинают с восстановления сайта после взлома с поиском точки входа, иначе взлом повторится.

Чек-лист: защищён ли ваш сайт от SQL-инъекций

  • Все запросы к базе используют параметры или ORM, сырой SQL со склейкой отсутствует или обоснован.
  • Поля сортировки, фильтров и поиска проверяются по белому списку.
  • Входные данные валидируются на сервере: тип, длина, формат.
  • У пользователя базы сайта нет прав на удаление таблиц и запись файлов.
  • Ошибки SQL не выводятся посетителям на продакшене.
  • CMS, плагины и модули обновлены, заброшенные расширения удалены.
  • Включён WAF, логи хранятся и хотя бы раз в месяц просматриваются.
  • Пароли пользователей хранятся в bcrypt или Argon2, бэкапы лежат вне сервера.
  • Есть назначенный ответственный и план действий на случай утечки, включая уведомление Роскомнадзора.
  • Код проверялся на уязвимости после последних крупных доработок.

Итог

SQL-инъекция — старая и хорошо изученная уязвимость, от которой давно есть надёжное средство: параметризованные запросы. Она по-прежнему в OWASP Top 10, потому что живёт в легаси-коде, сторонних модулях и срочных доработках, которые никто не перепроверял. Для бизнеса цена ошибки выросла: утечка клиентской базы — это уведомление регулятора в течение суток, штрафы в миллионы рублей и оборотный штраф при повторе. Проверить код дешевле, чем разбираться с последствиями.

Частые вопросы
Оба значения верны. Уязвимость — это ошибка в коде сайта, из-за которой ввод пользователя попадает в SQL-запрос как часть команды. Атака — попытка этой ошибкой воспользоваться. Закрывать нужно уязвимость: без неё атака невозможна, как бы часто её ни пробовали.
Ядро обеих CMS использует безопасные механизмы работы с базой, поэтому проблемы обычно возникают не в нём. Инъекции находят в сторонних плагинах и модулях, а также в самописных доработках: фильтрах, выгрузках, интеграциях. Поэтому важно обновлять расширения и проверять код, который писали под ваш проект.
Нет. HTTPS шифрует канал между браузером и сервером и защищает от перехвата данных по пути. Вредоносная строка приходит на сервер по тому же зашифрованному каналу и попадает в запрос так же, как без HTTPS. От инъекций защищает только правильная работа с базой в коде.
SQL-инъекция внедряет команды в запрос к базе данных на сервере и бьёт по данным: чтение, изменение, удаление. XSS внедряет JavaScript в страницу, который выполняется в браузере посетителя, и бьёт по пользователям: кража сессий, подмена форм. Обе уязвимости входят в категорию Injection в OWASP Top 10, но защищаются от них по-разному.
Прямых признаков часто нет: слепые инъекции не меняют работу сайта. Косвенно об атаке говорят запросы с кавычками и SQL-словами в логах, всплески медленных запросов к базе, новые учётки администраторов, жалобы клиентов на звонки мошенников, знающих детали заказов. Если есть подозрение, сохраните логи и проведите разбор инцидента.
Как временная мера — да: WAF отсекает массовые типовые атаки и даёт время на исправление. Но он не видит отложенные инъекции и пропускает нестандартные обходы, поэтому уязвимый код всё равно нужно переписать на параметризованные запросы. Если утечка случится, наличие WAF не освобождает от ответственности по 152-ФЗ.
Аудит безопасности сайта
Поможем с этой задачей под ключ — от идеи до результата. Рассчитаем стоимость и сроки под вашу задачу.
Читать подробнее
Услуги по теме
Проводим превентивный аудит безопасности сайта до того, как вас взломали: ищем уязвимости по методологии OWASP — SQL-инъекции, XSS, дыры в правах и доступах, разбираем устаревшую CMS, плагины и настройки хостинга, делаем пентест-лайт «чёрным» и «белым» ящиком. На выходе — понятный отчёт с уязвимостями, оценкой риска и приоритизированным планом устранения. Работаем на фикс-смете.
Восстанавливаем сайт после взлома и заражения вирусом: находим и удаляем вредоносный код, шеллы и бэкдоры, чистим базу данных, поднимаем сайт из бэкапа, снимаем блокировки антивирусов, хостинга и поисковиков, закрываем уязвимости и ставим защиту от повторного взлома. Работаем круглосуточно — берёмся в день обращения, на фикс-смете.
Берём ваш сайт на абонентское обслуживание: мониторинг доступности, бэкапы, обновления и безопасность, доработки по часам и реакция на инциденты по SLA. Студия с 2008 года — поддерживаем сайты на любой CMS и самописном коде.
Развиваем и дорабатываем существующий сайт: новый функционал, аккуратные правки, ускорение и рефакторинг — на Битрикс, WordPress, Yii, Laravel и любой другой CMS, даже если код писали не мы.