SQL-инъекции: общая информация
Серьезный тестировщик
Еще один тип атак на безопасность – это SQL-инъекции. Они могут нанести серьезный урон вашему приложению, поэтому очень важно найти эти уязвимости до того, как их найдет злоумышленник.
Осуществляя SQL-инъекцию, злоумышленник отправляет SQL-запрос через поле формы, которое взаимодействует с базой данных неожиданным образом. Вот четыре примера того, что этот нехороший человек может сделать при помощи такой атаки:
- Полностью удалить таблицу.
- Изменить запись о другом пользователе.
- Получить данные, к которым у него не должно быть доступа.
- Авторизоваться без правильных учетных данных.
Чтобы понять, как формируется SQL-инъекция, давайте разберем ее на примере. Предположим, у нас в приложении есть форма с полем имени пользователя. Когда в него вводят имя – например, "testerguy" – и отправляют это серверу, выполняется вот такой SQL-запрос:
SELECT * from users where username = 'testerguy'
Если такое имя существует в базе, результаты из таблицы пользователей передаются приложению.
Злоумышленник будет пытаться обмануть базу данных:
- Заставляя ее думать, что запись завершена, передавая имя с кавычкой: testerguy'
- Добавляя дополнительное условие, например, OR 1=1
- Добавляя завершающее выражение вроде ; чтобы убедиться, что другие SQL-выражения не выполнятся.
В вышеприведенном примере злоумышленник введет в поле имени примерно следующее:
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, чтобы заставить базу данных вернуть все имена пользователей в таблице.
- Завершающую строку -, чтобы база данных игнорировала все, идущее после нашего запроса.
Строка, переданная на сервер, будет в результате выглядеть так:
foo' OR 1=1--
можно заметить, что кнопка Submit пока неактивна – ведь мы не добавили пароль. Интерфейс ожидает ввода как имени, так и пароля, чтобы разрешить авторизацию. В поле пароля можно ввести что угодно вообще – мы уже позаботились о том, чтобы то, что мы туда введем, игнорировалось. Давайте напишем там bar.

Теперь при отправке запроса на авторизацию база данных получит вот что:
SELECT * from users where username = 'foo' OR 1=1--' AND password = 'bar'
Первая часть этого запроса возвращает всех пользователей, потому что 1=1 всегда истинно. Вторая часть запроса игнорируется, потому что в SQL все, идущее после дефисов – это комментарии. Код, видя, что запрос удачен и возвращены все пользователи, дает нам авторизоваться!
Если вы наведете курсор на иконку пользователя в левом верхнем углу экрана, вы увидите, что вошли как администратор! Его почтовый адрес был первым в базе данных, поэтому использовалась его учетка. Так как вы вошли под администратором, у вас теперь есть расширенный доступ к сайту, которого не могло бы быть, будь вы обычным пользователем.
Очевидно, что таких сценариев хорошо бы избежать, разрабатывая приложение! В следующий раз мы рассмотрим другие SQL-инъекции, которые можно использовать для тестирования на такую уязвимость.
Оригинал статьи: http://thethinkingtester.blogspot.com/2018/06/introduction-to-sql-injection.html
Перевод статьи: http://software-testing.ru/library/testing/security/3003-introduction-to-sql-injection