Код-ревью Junior Инъекции: SQL, NoSQL, команды обновлено

Ревью: поиск товаров на PHP

Вопрос

Найдите уязвимости в коде поиска товаров.

<?php
$pdo = new PDO($dsn, $user, $pass);
$q = $_GET['q'];
$sort = $_GET['sort'] ?? 'name';
$sql = "SELECT id, name, price FROM products WHERE name LIKE '%$q%' ORDER BY $sort";
$rows = $pdo->query($sql)->fetchAll();
foreach ($rows as $r) {
    echo "<li>" . $r['name'] . "</li>";
}

Коротко

Параметризация закрывает значения, allowlist закрывает идентификаторы, а экранирование при выводе закрывает XSS. Это три разные защиты для трёх разных контекстов.

Что должен найти ревьюер

  1. Безопасностьстрока 5
    SQL-инъекция через q: значение вклеено в строку. Нужен подготовленный запрос LIKE :q с параметром "%$q%".
  2. Безопасностьстрока 5
    SQL-инъекция через sort: имя колонки из запроса без проверки. Нужен allowlist (name, price).
  3. Безопасностьстрока 6
    query() с собранной строкой вместо prepare() + execute().
  4. Безопасностьстрока 8
    Хранимый XSS: название товара выводится без htmlspecialchars(..., ENT_QUOTES).

Разбор

Параметризация закрывает значения, allowlist закрывает идентификаторы, а экранирование при выводе закрывает XSS. Это три разные защиты для трёх разных контекстов.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.