Самый частый шаблон SQL инъекций в РНР — бесполезное экранирование символов

в 7:14, , рубрики: ONsec, php, sql-injection, sql-инъекция, аудит безопасности, безопасность веб-приложений, информационная безопасность, метки: , , , , ,

По роду своей деятельности, мне приходится выполнять аудиты безопасности исходного кода веб-приложений.
Много веб-приложений и много кода…

В этой статье я хотел бы поделиться одной простой (очень простой) истиной и статистикой, которые вывел и многократно проверил в течении трех последний лет просмотра тонн РНР кода.

Не секрет, что уязвимости внедрения операторов СУБД (SQL injections) являются самыми распространенными из всех серверных уязвимостей веб-приложений. Есть платформы и фреймворки, где такие вещи практически полностью исключены, например ORM'ом и прочим. Но статистика упорно говорит нам об абсолютном преобладании на просторах Интернета веб-приложений с простыми конкатенированными SQL запросами. Кроме того, есть случаи, где ORM вообще применим быть не может. Например, когда от пользовательских данных должны зависеть не только параметры выражений, но и сама логика запроса на уровне операторов.

Итак, начнем.

Бесполезное экранирование символов

Найдено в 83% РНР веб-приложений, уязвимых к SQL-инъекциям

Применение функции экранирования символов, таких как
mysql_escape_string
mysql_real_escape_string
addslashes
без обрамления кавычками. Чаще всего проявляется в числовых параметрах (всевозможные *_id).

Пример

$sql = "SELECT user FROM userslist WHERE userid=".mysql_real_escape_string($_GET['uid']);

На вид, это безопасный код, но только на вид. Сюда закрался самый частый в моей практике шаблон SQL-инъекций в РНР. Для проведения атаки на эту уязвимость от злоумышленника требуется просто не использовать символы " ' x00 r n x1a в векторе атаки.
Например:
/index.php?uid=-777 UNION SELECT password FROM userlist

Поиск в коде

Осложнен семантикой языка. Для простого поиска можно использовать egrep:
egrep -Rin "(select|update|insert|delete|replace).*(from|set|into).*(mysql_escape_string|mysql_real_escape_string|addslashes)" . | grep -v "["']['"]"

Логика поискового выражения такая — найти все строки, в которых слева от функций фильтрации нет последовательности символов кавычек ('', "", "', '"). Метод, разумеется, далеко не 100%, но требовать от регулярного выражения выполнить семантический анализ невозможно.
Для удобства вывода информации, можно подсветить функцию цветом в консоли:
egrep -Rin "(select|update|insert|delete|replace).*(from|set|into).*(mysql_escape_string|mysql_real_escape_string|addslashes)" . | grep -v "["']['"]" | egrep --color "(mysql_escape_string|mysql_real_escape_string|addslashes)"

Для защиты от этой шаблонной уязвимости, лучше всего использовать приведение типов.
Это всегда быстрее работает и надежнее чем всевозможные фильтрации и экранирования.
Для примера выше, патч может быть таким:
$sql = "SELECT user FROM userslist WHERE userid=".intval($_GET['uid']);

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

Автор: d0znpp

Поделиться

* - обязательные к заполнению поля