Однако плодотворная выдалась неделька…

В процессе исследования безопасности веб-приложения наткнулся на возможность проведения атаки типа внедрения операторов СУБД необычным образом.

Все пользовательские данные, которые попадают в базу при запросе типа INSERT фильтровались с помощью функции mysql_real_escape_string().

Однако, при определенном стечении обстоятельств, данные из базы являлись составной частью другого запроса к СУБД, в котором они уже не проходили фильтрацию.

Таким образом, через mysql_real_escape_string() удалось записать в базу данных строку вида:

‘ union all select version()/*

Которая, уже будучи составной частью другого запроса, который напрямую никак не зависел от пользовательских данных, уже сыграла роль классическое SQL инъекции.

В итоге второй запрос, который и давал выполнение операторов, выглядел следующим образом:

select mixvalue from datas where name like ‘%‘ union all select version()/*%’

Назвать такую штуку можно было как-нибудь типа “хранимая SQL инъекция”, но в виду связанности запросов мне больше понравился вариант “цепная SQL инъекция”.

Ниже привожу пример уязвимого кода.

<?php
$con = mysql_connect(“localhost”,”user”,”pass”);
if (!$con)
{
die(‘Could not connect: ‘ . mysql_error());
}

mysql_select_db(“dbase”, $con);

if (strlen($_GET['name'])>2) {
$r = mysql_query(“insert into sqli values(4, ‘”.mysql_real_escape_string($_GET['name']).”‘)”);
}

$result = mysql_query(“SELECT * FROM sqli”);

while($row = mysql_fetch_array($result))
{
echo “< p/ >User < font color=’red’>”.$row['name'].”</ font>”;
echo “< br />”;
$curname=$row['name'];
$r = mysql_query(“select mixtext from datas where mixtext like ‘%”.$curname.”%’”);
echo “< br/>Associated data:”;
while($row = mysql_fetch_array($r))
{
echo “< br/>——— “.$row['mixtext'];
}
}

mysql_close($con);
?>

Обращаю внимание разработчиков:

проверяйте данные, полученные из базы, которые Вы вставляете в запрос. Они могут попадать туда совершенно легально, но при этом нести инъекцию в другие запросы!

Демонстрашка:

Отдельное спасибо Ариану Ивансу (Arian Evans), за замечания касательно этого типа уязвимостей.

Most people just call this “blind SQL injection” and some call it “2nd
order Injection”

Но слепыми инъекциями это назвать как-то язык не поворачивает – в моем представлении это разделение по отображению непосредственно информации из базы данных. А на счет инъекций второй очереди – тут более удачно, но тоже не совсем корректно, такие инъекции, в общем случае, могут быть и N-ой очереди.