Одна із самих розпоширених проблем безпеки веб додатків називається SQL Injection (впровадження SQL–коду). Впровадження SQL–коду, назва говорить сама за себе, це спосіб взлому сайтів і програм які працюють з базами даних, основаних на впровадженні в запит (querry) довільного SQL–коду.
Впровадження SQL–коду складається в тому що зловмисник може виконати запит до бази даних (наприклад додати дані, стерти таблицю) отримати доступ до деяких локальних файлів на тому сервері на який здійснюється атака.
Ймовірність такої атаки висока в випадку некоретної обробки вхідних даних, які використовують в SQL–запитах.
В загальному і в цілому SQL Injection необхідно розуміти як уязвимість системи безпеки, через яку нападник може ввести різні дані або команди в РНР сторінку.
Для того щоб краще зрозуміти поняття і результат SQL Injection можна взяти в якості прикладу дуже розпоширену ситуацію. Ми часто зіштовхуємось з перевіркою достовірності веб додатків. Наприклад: по електронній почті. В даному випадку користовачу необхідно ввести імя користувача і пароль. Що стається після того як ми вводимо дані і натискаємо “Ок”.
Ці дані передаються в базу даних, де вони обробляються, і сервер реагує відповідним чином. Це і є якраз уязвиме місце, про яке йде мова. В цілому користувач може відправити дані типу input на сервер SQL (баз даних). Не виключно що ці дані можуть бути командами, шкідливими файлами, які можуть негативно впливати на роботу SQL— сервера, наприклад зловмисник може видалити записи даних і ввести інші непотрібні записи.
Допустимо у нас є веб–сторінка з входом (login), яка надає користувачу текстове поле для “Користувача” (User) а також поле для “Пароля”(Password). Коли користувач заповнює ці поля і натискає кнопку “Ок” тоді сторінка по замовчуванню використовує скрипт РНР, який автоматично заповнюється інформацією, представленою користувачем. Цей скрипт створює запит SQL і працює з базою даних.
Наприклад: Запит може бути в формі
strSQL = “SELECT”*FROM t_User” & _
“WHERE Username = ‘ ” & ” ‘ AND Password = ‘ ” & Password & ” ‘ ”
АБО
strSQL = ” SELECT”*FROM t_User” & _
“WHERE Username = ‘ ” & UserName & ” ‘
AND Password = ‘ ” & Password & ” ‘ ”
Хакер може використати цей скрипт, ввівши в поле “Username” наступну команду
‘ OR 1=1 —
Результатом буде:
WHERE Username = ” OR 1=1 — AND Password = ‘WHATEVER’
В прикладі вказано яким чином хакер вводить власний код в запит. В результаті поле Password більше не вважається важливим, і ми можемо отримати доступ до любого облікового запису без знання пароля.
Як захистити скрипти від SQL Injection
Оскільки коли стає зрозуміло що таке SQL Injection, тоді дуже важливо також дізнатись як можна захиститись від такого роду безпеки.
На щастя захиститись від SQL Injection не складно, а навпаки дуже просто. Необхідно дозволити діяти тільки одній опції для створення захищеного запиту. Все також залежить і від типу використованого РНР–розширення. Більшість використовують розширення “mysql’
Розширення РНР являє собою динамічні бібліотеки (набори підпрограм і обєктів). Розширення дозволяє доповнювати базові можливості мови, забезпечити роботу з базами даних, динамічною графікою, криптографічними бібліотеками, документами формату PDF.
Найчастіше для захисту від SQL Injection спеціалісти використовують функцію mysql_real_escape_string(). яка замінює спеціальні символи в unescaped_string беручи за увагу кодування зєднання таким чином, що результат можна безпечно використовувати в SQL–запиті в функції mysql_query().
Якщо вставляються бінарні дані, то до них також необхідно застосувати дану функцію.
Приклад:
Допустимо що в запиті нам необхідно виставити дужки. Але дужки будуть розпізнані не як символи всередині тексту, а як службовий символ закінчення рядка, і відповідно цілий текст після дужок буде розпізнаватись не як продовження тексту а як команди MySQL або РНР.
Для того щоб використовувати подібні символи як текст а не як службові символи, їх потрібно “екранувати” з використанням спеціального символу , наприклад за допомогою символу “слеш” “\”.
Функція mysql_real_escape_string() використовується для екранування службових символів, встановлений перед ними слеш (для екранування використовують і інші символи) mysql_real_escape_string() викликає бібліотечну функцію MySQL mysql_real_escape_string, яка додає зворотню косу риску до наступних символів: \x00; \n; \r; \; ‘,” and \xla
Дана функція повинна завжди використовуватись для того щоб зробити дані безпечнішими, які впроваджені в запит перед відправкою їх в MySQL.
Приклад mysql_real_escape_string() до кожної змінної, яка вставляється в запит, запобігає SQL Injection.
Код нижче являється найкращим варіантом складання запитів.
<?PHP
// Функція екранування змінних
function quote_smart($value)
{
// Якщо magic_quotes_gpe включена — використовуємо stripslashes
if (get_magic_quotes_gpe()) {
$ value = stripslashes($ value);
}
// Якщо змінна — число тоді екранувати не потрібно
// Якщо ні — тоді берем змінну в дужки і екрануємо
if (!is_numeric($value)) {
$ value = “” .mysql_real_escape_string($ value) . “”;
}
return $ value
}
// Зєднуємся
$linc = mycql_conect(‘mysql_host’,’mysql_user’,’mysql_password’)
OR die(mysql_erro());
// Складаємо безпечний запити
$query = sprint(“SELECT * FROM users WHERE user=%s AND password=%”;
qute_smart ($_POST[‘username’]),
qute_smart ($_POST[‘password’]);
mysql_query($query);
?>
<?PHP // Функція екранування змінних function quote_smart($value) { // Якщо magic_quotes_gpe включена — використовуємо stripslashes if (get_magic_quotes_gpe()) { $ value = stripslashes($ value); } // Якщо змінна — число тоді екранувати не потрібно // Якщо ні — тоді берем змінну в дужки і екрануємо if (!is_numeric($value)) { $ value = "" .mysql_real_escape_string($ value) . ""; } return $ value } // Зєднуємся $linc = mycql_conect('mysql_host','mysql_user','mysql_password') OR die(mysql_erro()); // Складаємо безпечний запити $query = sprint("SELECT * FROM users WHERE user=%s AND password=%"; qute_smart ($_POST['username']), qute_smart ($_POST['password']); mysql_query($query); ?>
Ще декілька правил безпеки.
⇒ не відкривайте зєднання з базою, використовуючи обліковий запис власника або адміністратора. Завжди старайтесь використовувати спецальностворених користувачів з максимально обмеженими правами.
⇒ обовязково перевіряйте введені дані на відповідність очікуваного типу. В РНР існує багато функцій для перевірки даних.
⇒ в випадку якщо додаток очікує цифрове введення, застосуйте функцію is_numeric() для провірки введених даних або змушено вкажіть їх тип за допомогою settype() або ж просто використовуйте числове подання за допомогою функції sprintf();
⇒ екрануйте любе нецифрове введення, використовуваний в запитах до бази даних.
⇒ не виводьте ніякої інформації в базі даних, особливо про її структуру.
⇒ якісно використовуйте інформацію, яка міститься в лог–файлі. Логування (внесення в журнал подій) може допомоготи при трасуванні взломаного додатку.