Последние учебники веб-разработки
 

SQL впрыскивание


SQL-инъекция может разрушить вашу базу данных.


SQL в веб-страниц

В предыдущих главах вы научились извлекать данные базы данных (и обновление), используя SQL.

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

Поскольку заявления SQL являются только текст, легко, с небольшим куском компьютерного кода, динамически изменять SQL операторы, чтобы предоставить пользователю с выбранными данными:

Код сервера

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

В приведенном выше примере, создает оператор выбора, добавив переменную (txtUserId) для выбранной строки. Переменная извлекается из пользовательского ввода (запрос) на странице.

Остальная часть этой главы описывает потенциальные опасности использования пользовательского ввода в SQL отчетности.


SQL-инъекция

SQL инъекция представляет собой метод, где злоумышленники могут вводить команды SQL в операторе SQL, с помощью ввода веб-страницы.

Введенные команды SQL может изменить SQL заявление и поставить под угрозу безопасность веб-приложения.


SQL Injection на основе 1 = 1 всегда истинно

Посмотрите на пример выше, еще один раз.

Допустим, что первоначальная цель кодекса было создать инструкцию SQL для выбора пользователя с данным идентификатором пользователя.

Если нет ничего , чтобы запретить пользователю ввод "wrong" вход, пользователь может ввести некоторые "smart" ввод так:

Идентификатор пользователя:

Результат сервера

SELECT * FROM Users WHERE UserId = 105 or 1=1

SQL-выше справедливо. Она возвращает все строки из таблицы пользователей, так как WHERE 1 = 1 всегда истинно.

Есть ли в приведенном выше примере, кажется опасным? Что делать, если таблица пользователей содержит имена и пароли?

SQL Приведенная выше так же, как это:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1

Умный хакер может получить доступ ко всем имена пользователей и пароли в базе данных, просто вставив 105 или 1 = 1 в поле ввода.


SQL Injection на основе ""="" всегда истинно

Здесь общая конструкция, используется для проверки входа пользователя на веб-сайт:

Имя пользователя:

Пароль:

Код сервера

uName = getRequestString("UserName");
uPass = getRequestString("UserPass");

sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"

Умный хакер может получить доступ к имени пользователя и пароля в базе данных, просто вставив "или ""=" в текстовое поле имя пользователя или пароль.

Код на сервере создаст допустимый оператор SQL, как это:

результат

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

Результат SQL действителен. Она возвращает все строки из таблицы пользователей, так как где "" = "" всегда истинно.


SQL Injection на основе Batched операторов SQL

Большинство баз данных поддерживают SQL заявление пакетного, разделенных точкой с запятой.

пример

SELECT * FROM Users; DROP TABLE Suppliers

SQL выше будет возвращать все строки в таблице Users, а затем удалите таблицу под названием поставщиков.

Если бы мы имели следующий код сервера:

Код сервера

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

И следующий ввод:

Идентификатор пользователя:

Код на сервере будет создать допустимый оператор SQL, как это:

результат

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers

Параметры для защиты

Некоторые веб - разработчики используют "blacklist" слов или символов для поиска в SQL ввода, чтобы предотвратить атаки SQL - инъекции.

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

(На самом деле это должно быть совершенно законно ввести оператор SQL в поле базы данных.)

Единственный доказанный способ защитить веб-сайт от атак путем внедрения SQL, заключается в использовании SQL параметров.

SQL параметры являются значениями, которые добавляются в запрос SQL во время выполнения, контролируемым образом.

ASP.NET Razor Пример

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Следует отметить, что параметры представлены в операторе SQL с помощью @ маркера.

SQL двигатель проверяет каждый параметр, чтобы убедиться, что это правильно для своей колонки и рассматриваются буквально, а не как часть SQL, которая будет выполнена.

Другой пример

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

Вы только что научились избегать инъекции SQL. Одним из главных уязвимостей веб-сайтов.


Примеры

Следующие примеры показывают, как создавать параметризованные запросы в некоторых распространенных веб-языков.

ЗЕЬЕСТ в ASP.NET:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserID);
command.ExecuteReader();

INSERT INTO заявление в ASP.NET:

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

INSERT INTO заявление в PHP:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();