Логотип schoolsw3.com
Учебники Справочники Упражнения КАК? Меню
Создать
Редактор Поддержка Форум

×
Учебники
Справочники
Упражнения
Пожертвовать Обновление Реклама Видео Магазин

SQL Учебник

SQL ГЛАВНАЯ SQL ВВЕДЕНИЕ SQL СИНТАКСИС SQL SELECT SQL SELECT DISTINCT SQL WHERE SQL ORDER BY SQL AND SQL OR SQL NOT SQL INSERT INTO SQL NULL ЗНАЧЕНИЕ SQL UPDATE SQL DELETE SQL SELECT TOP SQL MIN() и MAX() SQL COUNT(), AVG() и ... SQL LIKE SQL ЗНАКИ SQL IN SQL BETWEEN SQL ПСЕВДОНИМЫ SQL JOIN SQL INNER JOIN SQL LEFT JOIN SQL RIGHT JOIN SQL FULL OUTER JOIN SQL SELF JOIN SQL UNION SQL GROUP BY SQL HAVING SQL EXISTS SQL ANY и ALL SQL SELECT INTO SQL INSERT INTO SELECT SQL CASE SQL ФУНКЦИИ NULL SQL ХРАНИМАЯ SQL КОММЕНТАРИИ SQL ОПЕРАТОРЫ

SQL БАЗА ДАННЫХ

SQL СОЗДАТЬ БД SQL ОТКИНУТЬ БД SQL РЕЗЕРВНАЯ БД SQL СОЗДАТЬ ТАБЛИЦУ SQL ОТКИНУТЬ ТАБЛИЦУ SQL ИЗМЕНИТЬ ТАБЛИЦУ SQL ОГРАНИЧЕНИЯ SQL NOT NULL SQL UNIQU SQL PRIMARY KEY SQL FOREIGN KEY SQL CHECK SQL DEFAULT SQL CREATE INDEX SQL AUTO INCREMENT SQL ДАТЫ SQL CREATE VIEW SQL ИНЪЕКЦИЯ SQL ХОСТИНГ SQL ТИПЫ ДАННЫХ

SQL Справочник

SQL Ключевые слова MySQL Функции SQL Server функции MS Access функции SQL Краткий справочник

SQL Примеры

SQL Примеры SQL Викторина SQL Упражнения SQL Сертификат

SQL Инъекция



SQL Инъекция

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


В Веб странице

Инъекция обычно происходит, когда вы просите пользователя ввести данные, например его имя пользователя/идентификатор пользователя, и вместо имени/идентификатора пользователь дает вам инструкцию SQL, которую вы неосознанно запускаете к своей базе данных.

Посмотрите на следующий пример, который создает оператор SELECT, добавляя переменную (txtUserId) в строку select. Переменная извлекается из пользовательского ввода (getRequestString):

Пример

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

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


Инъекция, основанная на 1=1, всегда true

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

Если нет ничего, что могло бы помешать пользователю ввести "Неправильный" ввод, пользователь может ввести какой-то "Умный" ввод, например:

UserId:

Тогда оператор SQL будет выглядеть следующим образом:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

Приведенный выше SQL является допустимым и возвращает все строки из таблицы "Users", так как OR 1=1 всегда истинно.

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

Приведенная выше инструкция SQL во многом совпадает с этой:

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

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


Инъекция, основанная на ""="", всегда true

Вот пример входа пользователя на веб сайте:

Пользователь:

Пароль:

Пример

uName = getRequestString("username");
uPass = getRequestString("userpassword");

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

Результат

SELECT * FROM Users WHERE Name ="Щипунов Андрей" AND Pass ="мой_пароль"

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

Пользователь:

Пароль:

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

Результат

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

Приведенный выше SQL является допустимым и возвращает все строки из таблицы "Users", так как OR"="" всегда имеет значение TRUE.


Инъекция на основе пакетных инструкций SQL

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

Пакет инструкций SQL - это группа из двух или более инструкций SQL, разделенных точкой с запятой.

Приведенная ниже инструкция SQL вернет все строки из таблицы "Users", а затем удалит таблицу "Suppliers".

Пример

SELECT * FROM Users; DROP TABLE Suppliers

Посмотрите на следующий пример:

Пример

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

И следующие входные данные:

Пользователь:

Допустимая инструкция SQL будет выглядеть следующим образом:

Результат

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

Используйте параметры для защиты

Для защиты веб сайта от 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);

Примеры

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

SELECT STATEMENT IN 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 STATEMENT IN 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 STATEMENT IN 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();