# Занятие 2. SQL injection.
###### tags: `Intro to Web Security`

#### Материалы и описание для самостоятельного изучения:
- язык SQL
- [Что такое SQL и как он работает](https://gb.ru/posts/chto-takoe-sql-i-kak-on-rabotaet)
- [w3schools](https://www.w3schools.com/sql/default.asp)
- [sql-ex](https://sql-ex.ru)
- инъекции SQL
- [PortSwigger academy](https://portswigger.net/web-security/sql-injection)
- [sqlinjection.net](https://www.sqlinjection.net/tutorial/)
- [hacksplaining.com](https://www.hacksplaining.com/lessons)
## Слепая SQL инъекция
Возникает, когда приложение уязвимо для инъекции SQL, но его HTTP-ответы не содержат результатов соответствующего SQL-запроса или сведений о каких-либо ошибках базы данных.
С уязвимостями слепой SQL инъекции многие методы, например UNION attacks, неэффективны, поскольку они основаны на возможности видеть результаты введенного запроса в ответах приложения. Все еще возможно использовать слепую инъекцию SQL для доступа к несанкционированным данным, но необходимо использовать другие методы.

## Использование слепой инъекции SQL путем запуска условных ответов
Рассмотрим приложение, которое использует cookie отслеживания для сбора аналитических данных об использовании. Запросы к приложению включают заголовок cookie, подобный этому:
`Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4`
Когда обрабатывается запрос, содержащий TrackingId cookie, приложение определяет, действительный ли этот пользователь, используя такой SQL-запрос:
`SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'`
Этот запрос уязвим для SQLi, но результаты запроса не возвращаются пользователю. Однако приложение ведет себя по-разному в зависимости от того, возвращает ли запрос какие-либо данные. Если он возвращает данные (поскольку был отправлен распознанный идентификатор отслеживания), то на странице будет отображаться сообщение.
Этого поведения достаточно, чтобы использовать уязвимость слепой инъекции SQL и извлекать информацию, вызывая различные ответы, в зависимости от введенного условия.

## Получение условных ответов путем запуска ошибок SQL
В следующем примере предположим, что приложение выполняет один и тот же SQL-запрос, но не ведет себя по-разному в зависимости от того, возвращает ли запрос какие-либо данные. Предыдущий метод не будет работать, потому что введение различных логических условий не влияет на ответы приложения.
В этой ситуации часто можно заставить приложение возвращать условные ответы, вызывая ошибки SQL условно, в зависимости от введенного условия. Это включает в себя изменение запроса таким образом, чтобы он вызывал ошибку базы данных, если условие истинно, и не вызывал если условие ложно. Очень часто необработанная ошибка, вызванная базой данных, вызывает некоторую разницу в ответе приложения (например, сообщение об ошибке), что позволяет нам сделать вывод об истинности введенного условия.

## Использование слепой инъекции SQL путем запуска временных задержек
Предположим, что приложение теперь улавливает ошибки базы данных и корректно их обрабатывает. Запуск ошибки базы данных при выполнении введенного SQL-запроса больше не вызывает никаких изменений в ответе приложения, поэтому предыдущий метод создания условных ошибок не будет работать.
В этой ситуации часто можно использовать уязвимость слепой инъекции SQL, вызывая временные задержки условно, в зависимости от введенного условия. Поскольку SQL-запросы обычно обрабатываются приложением синхронно, задержка выполнения SQL-запроса также приведет к задержке HTTP-ответа. Это позволяет нам сделать вывод об истинности введенного условия на основе времени, затраченного до получения HTTP-ответа.

## Использование слепой инъекции SQL с использованием out-of-band (OAST)
Теперь предположим, что приложение выполняет один и тот же SQL-запрос, но делает это асинхронно. Приложение продолжает обработку запроса пользователя в исходном потоке и использует другой поток для выполнения SQL-запроса с использованием отслеживания cookie. Запрос по-прежнему уязвим для внедрения SQL, однако ни один из методов, описанных до сих пор, не будет работать: ответ приложения не зависит от того, возвращает ли запрос какие-либо данные, или от того, возникает ли ошибка базы данных, или от времени, затраченного на выполнение запроса.
В этой ситуации часто можно воспользоваться уязвимостью слепой инъекции SQL, запустив out-of-band сетевое взаимодействие с системой, которой вы управляете. Как и ранее, они могут запускаться условно, в зависимости от введенного условия, для вывода информации по одному биту за раз. Но что еще более важно, данные могут быть эксфильтрированы непосредственно в рамках самого сетевого взаимодействия.
Для этой цели можно использовать различные сетевые протоколы, но, как правило, наиболее эффективным является DNS (служба доменных имен). Это связано с тем, что очень многие производственные сети допускают свободный выход DNS-запросов, поскольку они необходимы для нормальной работы производственных систем.

## Как предотвратить слепые атаки SQL-инъекций?
Хотя методы, необходимые для поиска и использования уязвимостей слепой инъекции SQL, отличаются и более сложны, чем для обычной инъекции SQL, меры, необходимые для предотвращения инъекции SQL, одинаковы независимо от того, является ли уязвимость слепой или нет.
Как и в случае обычной SQL-инъекции, слепые атаки SQL-инъекции можно предотвратить за счет тщательного использования параметризованных запросов, которые гарантируют, что вводимые пользователем данные не могут повлиять на структуру предполагаемого SQL-запроса.

## Как предотвратить внедрение SQL
Большинство случаев внедрения SQL можно предотвратить, используя параметризованные запросы (также известные как подготовленные операторы) вместо объединения строк в запросе.
Следующий код уязвим для внедрения SQL, поскольку вводимые пользователем данные объединяются непосредственно в запрос:
`String query = "SELECT * FROM products WHERE category = '"+ input + "'";`
`Statement statement = connection.createStatement();`
`ResultSet resultSet = statement.executeQuery(query);`
Этот код можно легко переписать таким образом, чтобы пользовательский ввод не мешал структуре запроса:
`PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");`
`statement.setString(1, input);`
`ResultSet resultSet = statement.executeQuery();`

## Вывод
Чтобы параметризованный запрос эффективно предотвращал внедрение SQL, строка, используемая в запросе, всегда должна быть жестко запрограммированной константой и никогда не должна содержать никаких переменных данных из любого источника. Слишком легко ошибиться в отношении возможного происхождения данных или внести изменения в другой код, чтобы нарушить предположения о том, какие данные испорчены.

## Домашнее задание
### 1. Практика на PortSwigger
> Сдавать преподавателю в лс ВКонтакте - [Влад Соколов](https://vk.com/vavizh)
Решить лабу ["Атака с использованием SQL-инъекции, перечисляющая содержимое базы данных в бд, отличных от Oracle"](https://portswigger.net/web-security/sql-injection/examining-the-database/lab-listing-database-contents-non-oracle)