Учебник по SQL

SQL ГЛАВНАЯ Введение в SQL Синтаксис SQL Выбор SQL SQL выбрать отдельный SQL Где SQL И, Или, Не Порядок SQL по SQL вставить в Нулевые значения SQL Обновление SQL SQL Удалить SQL выберите вверху SQL Мин. и Макс. Количество SQL, среднее, сумма SQL нравится Подстановочные знаки SQL SQL входящий SQL между Псевдонимы SQL SQL-соединения Внутреннее соединение SQL Левое соединение SQL SQL правое соединение Полное соединение SQL Самостоятельное присоединение SQL Союз SQL Группа SQL по SQL Имея SQL существует SQL Любой, Все SQL выбрать в SQL вставить в выбор SQL-кейс Нулевые функции SQL Хранимые процедуры SQL Комментарии SQL SQL-операторы

База данных SQL

SQL Создать БД БД SQL Drop Резервная копия базы данных SQL Создание таблицы SQL Таблица удаления SQL Таблица изменений SQL Ограничения SQL SQL не нулевой Уникальный SQL Первичный ключ SQL Внешний ключ SQL Проверка SQL SQL по умолчанию Индекс SQL Автоматическое увеличение SQL Даты SQL Представления SQL SQL-инъекция Хостинг SQL Типы данных SQL

Ссылки на SQL

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

Примеры SQL

Примеры SQL SQL-викторина SQL-упражнения SQL-сертификат

SQL -инъекция


SQL-инъекция

Внедрение SQL — это метод внедрения кода, который может разрушить вашу базу данных.

SQL-инъекция — один из самых распространенных методов веб-хакерства.

Внедрение SQL — это размещение вредоносного кода в операторах SQL посредством ввода с веб-страницы.


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

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

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

Пример

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

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


Внедрение SQL на основе 1 = 1 всегда верно

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

Если ничто не мешает пользователю ввести «неправильный» ввод, пользователь может ввести какой-нибудь «умный» ввод, например:

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

Тогда оператор SQL будет выглядеть так:

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

Приведенный выше SQL действителен и вернет ВСЕ строки из таблицы «Пользователи», поскольку ИЛИ 1=1 всегда ИСТИНА.

Пример выше выглядит опасным? Что делать, если таблица «Пользователи» содержит имена и пароли?

Приведенный выше оператор SQL во многом похож на этот:

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

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



Внедрение SQL на основе ""="" всегда верно

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

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

Пароль:

Пример

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

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

Результат

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

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

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

Пароль:

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

Результат

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

Вышеупомянутый SQL действителен и вернет все строки из таблицы «Пользователи», поскольку ИЛИ «» =» всегда ИСТИНА.


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

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

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

Приведенный ниже оператор SQL вернет все строки из таблицы «Пользователи», а затем удалит таблицу «Поставщики».

Пример

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 — это значения, которые добавляются к запросу SQL во время выполнения контролируемым образом.

Пример Razor ASP.NET

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

Примеры

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

ВЫБЕРИТЕ ЗАЯВЛЕНИЕ В ASP.NET:

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

ВСТАВЬТЕ В ЗАЯВЛЕНИЕ В 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();

ВСТАВИТЬ В ЗАЯВЛЕНИЕ В 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();