Перейти к содержимому
← Каталог nodejs SQL Injection

SQL Injection: Second-Order через сохранённый username профиля

Second-order SQL injection: вредоносный username безопасно сохраняется при регистрации, но выполняется как часть SQL позже, когда обработчик профиля собирает запрос истории заказов конкатенацией.

hardnodejsPro
Задача
# SQL Injection: уязвимость второго порядка ## Сценарий Перед вами Express + Nunjucks приложение интернет-магазина SecureShop. Это нетипичная задача для SQLi: разработчик уже знает про класс проблемы и в очевидных местах работы с пользовательским вводом сделал всё правильно. В частности, форма регистрации использует параметризованные запросы — попытаться сделать SQLi прямо там не получится. Уязвимость находится не в **записи** пользовательских данных в БД, а в одном из мест **последующего чтения** этих данных. Где-то в обработчике, который запускается уже после того, как пользователь зарегистрирован и аутентифицирован, значение, **сохранённое в БД на этапе регистрации**, извлекается из неё и подставляется в **другой** SQL-запрос — и в этом другом запросе параметризации нет, идёт обычная строковая интерполяция. То есть данные, безопасно записанные при регистрации, при последующем чтении выходят за пределы своей роли «строка-литерал» и становятся частью SQL-синтаксиса. Это и есть классический SQLi второго порядка: payload «дремлет» в БД и срабатывает позже, в стороннем запросе. Ключевое заблуждение разработчика, ведущее к этому классу: «данные из БД — доверенные, мы же сами их туда положили». На самом деле данные из БД — это такой же недоверенный ввод, как параметры HTTP-запроса: атакующий мог их туда положить через любую точку входа, и единственный надёжный режим работы с ними — обращаться как с произвольной строкой и пропускать через параметризацию ровно так же, как и user input. В таблице пользователей есть привилегированная учётная запись `admin` с заказом, в котором фигурирует CTF-флаг. ## Цели 1. Найдите место в обработчике, где значение, **сохранённое в БД при регистрации пользователя**, при последующем чтении подставляется в SQL-запрос **через строковую интерполяцию** (а не через параметризацию). Подсказка: ищите не в обработчиках записи, а в обработчиках, которые читают что-то по имени текущего пользователя. 2. Зарегистрируйтесь с таким значением поля логина, чтобы при последующем чтении (в этом «втором» запросе) условие `WHERE` стало всегда истинным — то есть выборка возвращала записи всех пользователей, а не только текущего. 3. Войдите под этим аккаунтом, откройте страницу со списком заказов и заберите CTF-флаг прямо из её содержимого. ## Данные | Параметр | Значение | |----------|----------| | Обычный пользователь | `demo` / `demo` |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru