SQL-инъекции: общая информация |
09.04.2019 00:00 |
Автор: Кристин Джеквони (Kristin Jackvony) Еще один тип атак на безопасность – это SQL-инъекции. Они могут нанести серьезный урон вашему приложению, поэтому очень важно найти эти уязвимости до того, как их найдет злоумышленник. Осуществляя SQL-инъекцию, злоумышленник отправляет SQL-запрос через поле формы, которое взаимодействует с базой данных неожиданным образом. Вот четыре примера того, что этот нехороший человек может сделать при помощи такой атаки:
Чтобы понять, как формируется SQL-инъекция, давайте разберем ее на примере. Предположим, у нас в приложении есть форма с полем имени пользователя. Когда в него вводят имя – например, "testerguy" – и отправляют это серверу, выполняется вот такой SQL-запрос: SELECT * from users where username = 'testerguy' Если такое имя существует в базе, результаты из таблицы пользователей передаются приложению. Злоумышленник будет пытаться обмануть базу данных:
В вышеприведенном примере злоумышленник введет в поле имени примерно следующее: testerguy' OR 1=1; База данных в результате выполнит вот такой запрос: SELECT * from users where username = 'testerguy' OR 1=1;' Поразмыслите над условием 1=1. Оно всегда будет истинным, и база данных воспримет его как команду вернуть в ответе все, что находится в таблице! Таким образом, этот SELECT-запрос запрашивает все данные на всех пользователей. Давайте посмотрим на работу SQL-инъекции в действии путем работы с OWASP Juice Shop. Кликните на кнопку логина в левом верхнем углу экрана. Мы используем SQL-инъекцию для логина без правильных учетных данных. Мы предположим, что при запросе авторизации в базу вот такой запрос: SELECT * from users where username = 'testerguy' AND password = 'mysecretpass' Если этот запрос возвращает результаты, то предполагается, что пользователь существует и данные его верны, и вход осуществляется. Попробуем завершить выражение так, чтобы запрос вернул все имена пользователей, а пароли вообще игнорировались. Итак, отправим:
Строка, переданная на сервер, будет в результате выглядеть так: foo' OR 1=1-- можно заметить, что кнопка Submit пока неактивна – ведь мы не добавили пароль. Интерфейс ожидает ввода как имени, так и пароля, чтобы разрешить авторизацию. В поле пароля можно ввести что угодно вообще – мы уже позаботились о том, чтобы то, что мы туда введем, игнорировалось. Давайте напишем там bar. Теперь при отправке запроса на авторизацию база данных получит вот что: SELECT * from users where username = 'foo' OR 1=1--' AND password = 'bar' Первая часть этого запроса возвращает всех пользователей, потому что 1=1 всегда истинно. Вторая часть запроса игнорируется, потому что в SQL все, идущее после дефисов – это комментарии. Код, видя, что запрос удачен и возвращены все пользователи, дает нам авторизоваться! Если вы наведете курсор на иконку пользователя в левом верхнем углу экрана, вы увидите, что вошли как администратор! Его почтовый адрес был первым в базе данных, поэтому использовалась его учетка. Так как вы вошли под администратором, у вас теперь есть расширенный доступ к сайту, которого не могло бы быть, будь вы обычным пользователем. Очевидно, что таких сценариев хорошо бы избежать, разрабатывая приложение! В следующий раз мы рассмотрим другие SQL-инъекции, которые можно использовать для тестирования на такую уязвимость. |