НАЙКРАЩИЙ САЙТ ДЛЯ ВЕБ-РОЗРОБНИКІВ

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() and MAX() SQL COUNT() SQL SUM() SQL 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 Create DB SQL Drop DB SQL Backup DB SQL Create Table SQL Drop Table SQL Alter Table SQL Constraints SQL Not Null SQL Unique SQL Primary Key SQL Foreign Key SQL Check SQL Default SQL Index SQL Auto Increment SQL Dates SQL Views SQL Injection SQL Hosting SQL Типи даних

SQL Довідники

SQL Ключові слова MySQL Функції SQL Серверні функції MS Access Функції SQL Швидкий довідник

SQL Приклади

SQL Приклади SQL Редактор SQL Вікторина SQL Вправи SQL Bootcamp SQL Сертифікат

SQL. W3Schools українською. Уроки для початківців

En

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 завжди True

Подивіться на приклад вище ще раз. Початковою метою коду було створити оператор SQL для вибору користувача з заданим ідентифікатором (id) користувача.

Якщо ніщо не заважає користувачеві ввести "неправильний" input, користувач може ввести якийсь "розумний" input, як це:

UserId:

Тоді SQL інструкція виглядатиме так:

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

Наведений вище SQL дійсний і поверне ВСІ рядки з таблиці "Users", оскільки OR 1=1 завжди TRUE.

Чи виглядає наведений вище приклад небезпечним? Що робити, якщо таблиця "Users" містить імена та паролі?

Наведена вище SQL інструкція майже така сама:

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

Хакер може отримати доступ до всіх імен користувачів і паролів у базі даних, просто вставивши 105 АБО 1=1 у поле введення.


SQL Ін’єкція на основі ""="" завжди True

Ось приклад входу користувача на веб-сайт:

Username:

Password:

Приклад

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"

Хакер може отримати доступ до імен користувачів і паролів у базі даних, просто вставивши " OR ""=" у текстове поле імені користувача (User Name) чи пароля (Password):

User Name:

Password:

Код на сервері створить таку валідну (дійсну) SQL інструкцію:

Результат

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

Наведений вище SQL валідний і повертатиме всі рядки з таблиці "Users", оскільки OR ""="" завжди має значення TRUE.


SQL Ін’єкція на основі пакетних SQL інструкцій

Більшість баз даних підтримують групову SQL інструкцію.

Пакет інструкцій SQL – це група з двох або більше інструкцій SQL, розділених крапкою з комою.

Наведена нижче SQL інструкція поверне всі рядки з таблиці "Users" ("Користувачі"), а потім видалить таблицю "Suppliers" ("Постачальники").

Приклад

SELECT * FROM Users; DROP TABLE Suppliers

Подивіться на наступний приклад:

Приклад

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

І наступний input (введення):

User id:

Валідна SQL інструкція виглядатиме так:

Результат

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

Використовуйте параметри 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);

Приклади

У наведених нижче прикладах показано, як створювати параметризовані запити деякими поширеними веб-мовами.

SELECT інструкція в 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();