Уязвимость в Chocomart.kz (SQLi)
О проблеме я написал в Chocomart и она быстро была устранена (надеюсь полностью). У меня небольшой SQL опыт и поэтому в посте ничего нового. Но начинающим разработчикам все же будет интересно.
SQL Injection - это техника вставки кода, когда в запросе присутствует произвольный SQL-код. Обычно это происходит из-за некорректной обработки данных. Атакующий может получить полный доступ к базе данных. SQL injection впервые был описан в 1998 году.
На странице chocomart.kz/subscribe есть форма с автозаполнением где нужно выбрать свой город. Для примера представим, что SQL запрос выглядит так:
‘SELECT * FROM cities WHERE City LIKE ‘+ $_POST[‘query’] +’%;’
То есть, находим город по первым буквам названия города. Но, если напечатать abc%’ OR 1=1#; вместо города, то полный запрос будет таким:
SELECT * FROM cities WHERE City LIKE ‘abc%’ OR 1=1#; %’;
Запрос возвращает все города. Символ # используется для комментирования, что позволяет нам “удалить” продолжение запроса.
Как эксплуатировать эту уязвимость: с помощью UNION SELECT 1, 2, 3 узнаем используемый столбец.
Теперь, чтобы увидеть ответы на запросы, достаточно вставить SQL код вместо символа 2. UNION SELECT 1, database(), 3 вер нет имя базы данных.
Что эта за база данных? Посмотрим на имена таблиц.
Читая имена таблиц можно понять, что это полная база данных Chocomart (корзина, заказы, аккаунты, адреса, логи платежей и т.д.). После этого, я перестал делать запросы и не стал узнавать есть ли права на запись.
Хотя скачать всю базу данных - это вопрос времени. Узнав имя таблицы, вы сможете узнать имена столбцов. Мошенникам даже не нужно делать это “вручную” на вашем сайте.
Программы как sqlmap позволяют делать это в окне терминала. Запустите скрипт и через пару часов (или дней) у вас будет вся база данных в формате CSV. Пример с сайта sqlmap:
Кстати, сайт Chocomart показывал полный стек-трейс при ошибке SQL. Если вы не видите стек-трейс при синтаксической ошибке, то это называется слепой (blind) injection. Это немного усложняет атаку.
Нужно помнить, что многие современные веб фреймворки идут с ORM (object-relational mapping) и вам не нужно самим писать SQL. Это ускоряет разработку и помогает защититься от большей части SQL инъекции (вы не собираете запрос “по кускам”).
Если вас не устраивает производительность запросов при ORM, то стоит подумать о хранимых процедурах (stored procedures) или параметризированных запросах (parametrized queries).
Если же вы все-таки решили писать “сырой” SQL, то разработчикам нужно убедиться, что их приложения не уязвимы к SQLi атакам. Подробнее про SQL инъекции можно узнать здесь.