Статья [2] - Безопасный PHP. Защита от SQL-Injection

5ZyfKYLxSM40DJxnK3SQ_05174717707032-t1200x480.jpg

Всем Салам и всех с Новым Годом. Праздники праздниками, но знания получать нужно, чем мы сейчас займемся. Как вы уже знаете по названию, сегодня мы будем разбирать SQL-Injection в PHP. Как подметили в прошлой статье про XSS, что XSS тематика обширная и не все рассмотрено.

И я хочу сказать цикл статей посвящен безопасности PHP, а не самим видам уязвимостей. Поэтому, в конце я буду кидать ссылки, для более детального изучения данной уязвимости. А мы с вами будем разбирать, какой-нибудь 1 случай и как делать, чтобы наш PHP код был безопасным.

[0] - SQL-Injection. Что такое?

Итак, что за зверь вообще SQL-инъекция, простыми словами, данная уязвимость позволяет получить доступ к базе данных из-за неправильно написанного нами кода. Из-за того, что, мы не экранируем запросы. Более подробнее ниже по ссылкам.

И как обычно, для общего понимания, и потому что я люблю решать всякие таски, начнем именно с таска с рутми. Возьмем этот таск:

Как мы видим у нас тут есть какой-то CMS и какие-то ссылки. Ну для начала тупо тыкаем по ссылкам.
1.jpg


И видим сразу, в базу передаются данные GET запросом, и если тыкнуть кавычку, то запрос рушится и получаем ошибку. Произошло из-за того, что запросы не экранируются, а напрямую передаются в БД.
2.jpg


Теперь определим количество полей и будем получать данные с помощью UNION, т.е. объединения запросов из БД. И как видим ниже, количество полей =< 3
3.1.jpg

3.2.jpg

4.1.jpg

4.2.jpg


В итоге получаем админский доступ.
5.jpg


[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'];

6.jpg

6.1.jpg


[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'];
}

7.jpg


И думаю вы понимаете, что может произойти, если злоумышленник получает доступ к нашему БД, тупо удалить все и еще многое другое.

[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'];
}
}

8.1.jpg


Как видим, какие либо 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.

  1. Серия статей SQL-Injection для начинающих:
  2. Мощный, полный мануал по эксплуатации:
  3. По SQL мне сильно нравится:
  4. Для тренировки можете использовать: root-me.org, alexbers.com/sql/, habrahabr.ru/post/250551/, dvwa.co.uk

Для понимания того, как мы экранируем запросы:

  • И про PDO:

Всем удачи. И профита в Новом году!

Часть 1: Безопасный PHP. Защита от XSS атак.
 
Последнее редактирование:
21.12.2017
5
0
BIT
11
Как это понять?
Скрытое содержимое, Вам необходимо иметь сообщений: 0, а сейчас у Вас сообщений:2.
 

Citizen0

Green Team
07.02.2017
203
228
BIT
0
PHP:
$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'];
}
}
Последняя скобка лишняя

PHP:
$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'];
    }
}
- Откуда взялась переменная $mysqli?
- Если указываете MYSQLI_NUM, то нужно использовать числовые индексы
PHP:
        echo 'Username: ' .$row[0]. '<br>';
        echo 'Password: ' .$row[1];
 
  • Нравится
Реакции: Vertigo и r0hack
M

maxoun

В 21 веке SQL инъекция она не опасная, так как полно методов защиты.
Те же самые подготовленные запросы, или к примеру регулярные выражения.
Методами PHP. и т.д.
 

Iskus

Green Team
13.11.2017
287
468
BIT
0
В 21 веке SQL инъекция она не опасная, так как полно методов защиты.
Те же самые подготовленные запросы, или к примеру регулярные выражения.
Методами PHP. и т.д.
Что за бред ты несёшь? Может ты про слепые скули не слышал?
 
  • Нравится
Реакции: r0hack
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!