Всем Салам и всех с Новым Годом. Праздники праздниками, но знания получать нужно, чем мы сейчас займемся. Как вы уже знаете по названию, сегодня мы будем разбирать SQL-Injection в PHP. Как подметили в прошлой статье про XSS, что XSS тематика обширная и не все рассмотрено.
И я хочу сказать цикл статей посвящен безопасности PHP, а не самим видам уязвимостей. Поэтому, в конце я буду кидать ссылки, для более детального изучения данной уязвимости. А мы с вами будем разбирать, какой-нибудь 1 случай и как делать, чтобы наш PHP код был безопасным.
[0] - SQL-Injection. Что такое?
Итак, что за зверь вообще SQL-инъекция, простыми словами, данная уязвимость позволяет получить доступ к базе данных из-за неправильно написанного нами кода. Из-за того, что, мы не экранируем запросы. Более подробнее ниже по ссылкам.
И как обычно, для общего понимания, и потому что я люблю решать всякие таски, начнем именно с таска с рутми. Возьмем этот таск:
Ссылка скрыта от гостей
Как мы видим у нас тут есть какой-то CMS и какие-то ссылки. Ну для начала тупо тыкаем по ссылкам.
И видим сразу, в базу передаются данные GET запросом, и если тыкнуть кавычку, то запрос рушится и получаем ошибку. Произошло из-за того, что запросы не экранируются, а напрямую передаются в БД.
Теперь определим количество полей и будем получать данные с помощью UNION, т.е. объединения запросов из БД. И как видим ниже, количество полей =< 3
В итоге получаем админский доступ.
[1] - Эксплуатация SQL-Injection в PHP
На данный момент безопасно мы можем коннектится к БД и проводить с ним определенные манипуляции с помощью PDO или MySQLI. Разберем оба момента.
[1.1] - PDO
У нас имеется такой код, где есть уязвимость, где данные получаемые мы никак не фильтруем и отправляем что попало в БД.
Код:
$id = $_GET['id'] ?? 'Пусто';
$connect = new PDO('mysql:dbname=codeby;host=localhost', 'root', '');
$sql = "SELECT username, password FROM codeby_sql WHERE id = " . $id;
foreach ($connect->query($sql) as $row) {
echo 'Username: ' .$row['username']. '<br>';
echo 'Password: ' .$row['password'];
[1.2] - MySQLI
Теперь рассмотрим уязвимость, если MySQLI.
Код:
$id = $_GET['id'] ?? 'Пусто';
$connect = new mysqli('localhost', 'root', '', 'codeby');
if ($connect->connect_error) {
die($connect->connect_errno);
}
$query = "SELECT username, password FROM codeby_sql WHERE id = " . $id;
foreach ($connect->query($query) as $row) {
echo 'Username: ' .$row['username']. '<br>';
echo 'Password: ' .$row['password'];
}
И думаю вы понимаете, что может произойти, если злоумышленник получает доступ к нашему БД, тупо удалить все и еще многое другое.
[2] - Как обезопасить PHP от SQL-Injection
Также рассмотрим варианты закрытия этих уязвимостей. И сразу скажу, что экранировать мы наши запросы будем с помощью хранимых процедур (prepared statements)
[2.1] - PDO
Код:
$id = $_GET['id'] ?? 'Пусто';
$connect = new PDO('mysql:dbname=codeby;host=localhost', 'root', '');
$sql = "SELECT username, password FROM codeby_sql WHERE id = :id";
$sth = $connect->prepare($sql, [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);
$sth->execute([':id' => $id]);
while ($row = $sth->fetch()) {
echo 'Username: ' .$row['username']. '<br>';
echo 'Password: ' .$row['password'];
}
}
Как видим, какие либо SQL запросы и кавычки и все остальное у нас фильтруются.
[2.2] - MySQLI
В MySQLI, для этого у PHP имеется своя функция mysqli_real_escape_string(), почти нас защищает, но все-таки тут также лучше использовать хранимые процедуры.
Код:
$id = $_GET['id'] ?? 'Пусто';
$connect = new mysqli('localhost', 'root', '', 'codeby');
$query = "SELECT username, password FROM codeby_sql WHERE id = ?";
$sth = $mysqli->stmt_init();
if ($sth->prepare($query)) {
$sth->bind_param("i", $id);
$sth->execute();
$result = $sth->get_result();
while ($row = $result->fetch_array(MYSQLI_NUM)) {
echo 'Username: ' .$row['username']. '<br>';
echo 'Password: ' .$row['password'];
}
}
На этом наверное у нас все, если интересуют какие-то отдельные моменты, то можете писать в комментах
В конце как и говорил, выложу список ссылок для подробного изучения SQL-Injection.
И забыл упомянуть, что нужно иметь какие-то базовые знания по SQL.
- Серия статей SQL-Injection для начинающих:
Ссылка скрыта от гостей
- Мощный, полный мануал по эксплуатации:
Ссылка скрыта от гостей
- По SQL мне сильно нравится:
Ссылка скрыта от гостей
- Для тренировки можете использовать: root-me.org, alexbers.com/sql/, habrahabr.ru/post/250551/, dvwa.co.uk
Для понимания того, как мы экранируем запросы:
-
Ссылка скрыта от гостей
- И про PDO:
Ссылка скрыта от гостей
Всем удачи. И профита в Новом году!
Часть 1: Безопасный PHP. Защита от XSS атак.
Последнее редактирование: