SQL-инъекции и параметризованные запросы
Устраняйте риски инъекций, всегда используя подготовленные выражения с PDO
«SQL-инъекции и параметризованные запросы» — бесплатный урок PHP Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения PHP Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс PHP Academy содержит 4 уроков всего.
Что такое внедрение SQL-кода?
Внедрение SQL-кода возникает, когда предоставленные пользователем данные напрямую встраиваются в SQL-запрос, позволяя злоумышленникам изменять запрос и получать доступ к данным, изменять или удалять их.
Классический пример
Конкатенация пользовательского ввода в SQL:
<?php
// VULNERABLE: attacker enters username = "' OR '1'='1"
$sql = "SELECT * FROM users WHERE username = '".$_GET["username"]."'";
// Becomes: SELECT * FROM users WHERE username = '' OR '1'='1'
// Returns ALL users!Пример извлечения данных
Злоумышленник использует UNION SELECT, чтобы получить данные из других таблиц.
// Input: ' UNION SELECT username, password FROM admin_users--
// This appends a second SELECT returning admin credentialsПодготовленные выражения — решение
При использовании подготовленных выражений структура запроса фиксируется до передачи любых данных. База данных обрабатывает все связанные значения как литеральные данные, а не как код SQL.
<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_GET["username"]]);
// Safe even if username = "' OR 1=1--"Именованные заполнители
Именованные заполнители понятнее, особенно при наличии нескольких параметров.
<?php
$stmt = $pdo->prepare(
"SELECT * FROM users WHERE email = :email AND active = :active"
);
$stmt->execute([":email" => $email, ":active" => true]);Eloquent безопасен по умолчанию
Laravel Eloquent использует подготовленные выражения PDO внутри всех стандартных операций построителя запросов.
<?php
// Safe:
User::where("email", $email)->first();
// UNSAFE: raw query with user input!
DB::select("SELECT * FROM users WHERE email = ".$email);Необработанные запросы
Если в Laravel необходимо использовать необработанный SQL, всегда применяйте привязку параметров.
<?php
// Safe raw query:
$users = DB::select("SELECT * FROM users WHERE email = ?", [$email]);
// Or with named bindings:
$users = DB::select("SELECT * FROM users WHERE email = :email", [":email" => $email]);Внедрение через предложение LIKE
Предложения LIKE требуют особой обработки: символы подстановки (%, _) необходимо экранировать вручную перед привязкой.
<?php
$search = str_replace(["%", "_", "\\"], ["\%", "\_", "\\\\"], $userInput);
$stmt = $pdo->prepare("SELECT * FROM products WHERE name LIKE ?");
$stmt->execute(["%$search%"]);Внедрение через ORDER BY
Имена столбцов и направления сортировки ORDER BY нельзя параметризовать. Проверяйте их по белому списку.
<?php
$allowedColumns = ["name", "price", "created_at"];
$col = in_array($request->sort, $allowedColumns) ? $request->sort : "name";
$dir = $request->dir === "desc" ? "desc" : "asc";
// Then safely build the query stringХранимые процедуры
Хранимые процедуры также могут быть уязвимыми, если внутри них выполняется конкатенация входных данных. Всегда используйте вызовы с параметрами.
Принцип минимальных привилегий
Пользователь базы данных, подключающийся из PHP, должен иметь только права SELECT/INSERT/UPDATE/DELETE для необходимых таблиц — и никогда не должен получать права CREATE, DROP или права администратора.
Итоги
ALWAYS используйте подготовленные выражения со связанными параметрами. Никогда не объединяйте пользовательский ввод с SQL через конкатенацию. Проверяйте ORDER BY и имена столбцов по белому списку. Используйте PDO с отключённой эмуляцией подготовки выражений.
Быстрая проверка
Как правильно защититься от внедрения SQL-кода?
Часто задаваемые вопросы
Урок «SQL-инъекции и параметризованные запросы» бесплатный?
Да — полный текст урока «SQL-инъекции и параметризованные запросы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс PHP Academy, подпишись на CoddyKit PRO. Курс PHP Academy содержит 4 уроков всего.
Чему я научусь в уроке «SQL-инъекции и параметризованные запросы»?
Устраняйте риски инъекций, всегда используя подготовленные выражения с PDO Ты практикуешь PHP Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать PHP Academy?
Предыдущий опыт не требуется. PHP Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «SQL-инъекции и параметризованные запросы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке PHP Academy?
Да. Каждый урок PHP Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Защита от межсайтового скриптинга (XSS)
- SQL-инъекции и параметризованные запросы
- Защита от CSRF
- Безопасное хранение паролей