Ответ
SQL-инъекция — это уязвимость, возникающая при неправильной обработке пользовательского ввода, который подставляется в SQL-запрос. Атакующий может внедрить вредоносный SQL-код, что приведёт к выполнению нежелательных операций (чтение, изменение, удаление данных и т. д.).
Пример уязвимого кода:
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
Если ввести ' OR '1'='1 в поле username, запрос превратится в:
SELECT * FROM users WHERE username='' OR '1'='1' AND password='...'
Это вернёт все записи из таблицы users.
Защита:
- Используйте подготовленные выражения (PDO/mysqli):
$stmt = $pdo->prepare("SELECT * FROM users WHERE username=:username AND password=:password");
$stmt->execute(['username' => $username, 'password' => $password]);
- Валидация и экранирование ввода.
- Принцип минимальных привилегий для БД.
Ответ 18+ 🔞
Э, слушай, вот тебе история про то, как твой код может накрыться медным тазом, если ты не следишь за тем, что в него суют.
Представь, у тебя есть форма входа. Пользователь вводит логин и пароль, а твой скрипт, как доверчивый лох, тупо лепит это всё в SQL-запрос. Вот так, блядь:
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
Выглядит вроде норм, да? А теперь смотри сюда, какой-нибудь хитрожопый пидарас шерстяной может в поле username вписать не 'admin', а вот такую хуйню: ' OR '1'='1.
И что получается? Твой запрос, ёпта, превращается в полную пиздопроебибну:
SELECT * FROM users WHERE username='' OR '1'='1' AND password='...'
А '1'='1' — это всегда правда, ядрёна вошь! И этот запрос вернёт тебе вообще всех пользователей из таблицы. А если там первая запись — это админ, то злоумышленник заходит как админ, и доверия к твоему коду — ноль ебать. Сам от себя охуеешь, когда это обнаружат.
Как не быть распиздяем и защититься?
- Используй подготовленные выражения. Это святое, блядь. Всё равно, через PDO или mysqli. Смысл в том, что запрос и данные отправляются в базу отдельно, и никакой пользовательский ввод уже не может изменить структуру запроса. Вот, смотри, как надо:
$stmt = $pdo->prepare("SELECT * FROM users WHERE username=:username AND password=:password");
$stmt->execute(['username' => $username, 'password' => $password]);
Вот это — надёжно. Запрос уже скомпилирован, места для подстановки чётко обозначены, и туда никакую левую хуйню не воткнуть.
- Валидируй и экранируй ввод. Но это, честно, уже второй эшелон. Подготовленные выражения — главное оружие.
- Принцип минимальных привилегий для БД. Не заводи от имени приложения суперпользователя, который может всё. Дай ему права только на SELECT, INSERT, UPDATE в нужных таблицах. Пусть даже если его как-то взломают, он не сможет наделать делов — дропнуть базу или всю схему переписать. Это как не давать гостю ключи от сейфа, а только от туалета.
Короче, чувак, если будешь тупо склеивать строки для SQL — ты ходишь по охуенно тонкому льду. Рано или поздно провалишься. Используй подготовленные выражения, и спи спокойно.