Проблемы запросов в PDO в PHP

Как вы уже должны знать, SQL запросы подвержены SQL-инъекциям. Расширение PDO призвано бороться с инъекциями, но просто так, по умолчанию, оно этого не делает.

Давайте посмотрим на проблему на примере. Пусть у нас есть следующий запрос, в который вставляется переменная:

php<?php
  $sql = "SELECT * FROM users WHERE id=$id";
  $res = $pdo->query($sql);
?>

Пусть наша переменная приходит откуда-то извне, например, из GET-параметра. Для простоты, однако, давайте просто зададим ее значение вручную. Мы ожидаем некоторое числовое значение, например, такое:

php<?php
  $id = 1;
?>

Злобный хакер, однако, может передать следующее значение (считаем, что у нас есть поле role):

php<?php
  $id = '-1 OR role="admin"';
?>

Получается, что мы хотели следующий запрос:

php<?php
  $sql = "SELECT * FROM users WHERE id=1";
  $res = $pdo->query($sql);
?>

А получили следующий, который вытягивает администратора сайта:

php<?php
  $sql = "SELECT * FROM users WHERE id=-1 OR role="admin"";
  $res = $pdo->query($sql);
?>

Чтобы избежать такой ситуации, в PDO предусмотрен специальный механизм, который называется подготовленные запросы. Их мы будем разбирать в следующем уроке.

Задание 1

Намеренно осуществите SQL-инъекцию к вашей базе.