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();