forked from vlsergey/infosec
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsql-injections.tex
More file actions
36 lines (31 loc) · 5.65 KB
/
Copy pathsql-injections.tex
File metadata and controls
36 lines (31 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
\section[SQL-инъекции с исполнением кода веб-сервером]{SQL-инъекции с исполнением кода \protect\\ базой данных интернет-сервиса}
\selectlanguage{russian}
Второй классической уязвимостью веб-приложений являются SQL-инъекции, когда пользователь имеет возможность поменять смысл запроса к базе данных веб-сервера. Запрос делается в виде текстовой строки на скриптовом языке SQL. Например, выражение
\begin{verbatim}
s = "SELECT * FROM Users WHERE Name = '" + username + "';"
\end{verbatim}
предназначено для получения информации о пользователе \texttt{username}. Однако если пользователь вместо имени введёт строку вида
\begin{center} \begin{verbatim}
john'; DELETE * FROM Users; SELECT * FROM Users WHERE
Name = 'john,
\end{verbatim} \end{center}
то выражение превратится в три SQL-операции:
%{\color{red} Проверить в каких системах будет работать. В JDBC PrepareStatement требует одно выражение, а ExecutableStatement использовать нельзя, так как он не возвращает значения.}
\begin{verbatim}
-- запрос о пользователе john
SELECT * FROM Users WHERE Name = 'john';
-- удаление всех пользователей
DELETE FROM Users;
-- запрос о пользователе john
SELECT * FROM Users WHERE Name = 'john';
\end{verbatim}
При выполнении этого SQL-запроса к базе данных все записи пользователей будут удалены.
Уязвимости в SQL-выражениях являются частным случаем уязвимостей, связанных с использованием сложных систем с разными языками управления данными, и, следовательно, с разными системами экранирования специальных символов и контроля над типом данных. Когда веб-сервер принимает от клиента данные, закодированные обычно с помощью <<application/x-www-form-urlencoded>>~\cite{html4:1999}, специальные символы (пробелы, неалфавитные символы и~т.\,д.) корректно экранируются браузером и восстанавливаются непосредственно веб-сервером или стандартными программными библиотеками. Аналогично, когда SQL-сервер передаёт или принимает данные от клиентской библиотеки, внутренним протоколом общения с SQL-сервером происходит кодировка текста, который является частью пользовательских данных. Однако на стыке контекстов -- в тот момент, когда программа, выполняющаяся на веб-сервере, уже приняла данные от пользователя по HTTP-протоколу\index{протокол!HTTP} и собирается передать их SQL-серверу в качестве составной части SQL-команды -- перед программистом стоит сложная задача учёта, в худшем случае, трёх контекстов и кодировок: входного контекста протокола общения с клиентом (HTTP), контекста языка программирования (с соответствующим оформлением и экранированием специальных символов в текстовых константах) и контекста языка управления данными SQL-сервера.
Ситуация усложняется тем, что программист может являться специалистом в языке программирования, но может быть не знаком с особенностями языка SQL или, что чаще, конкретным диалектом языка SQL, используемым СУБД.
Метод защиты заключается в \emph{разделении} кода и данных. Для защиты от приведённых атак на базу данных следует использовать параметрические запросы к базе данных с \emph{фиксированным} SQL-выражением. Например, в JDBC~\cite{jdbc:2006}:
\begin{verbatim}
PreparedStatement p = conn.prepareStatement(
"SELECT * FROM Users WHERE Name=?");
p.setString(1, username);
\end{verbatim}
Таким образом, задача корректного оформления текстовых данных для передачи на SQL-сервер перекладывается на драйвер общения с СУБД, в котором эта задача обычно решена корректно авторами драйвера, хорошо знающими особенности протокола и языка управления данными сервера.