Php & Sql Injection – UTF8 POC

Существует много разговоров о том, как функции addlashes и mysql_real_escape небезопасны для предотвращения инъекций. Истина заключается в том, что даже большие рамки или CMS, такие как WordPress, используют эти функции и до сих пор выполняют божественную работу.

Я знаю, что есть некоторые конкретные сценарии при использовании кодировки GBK, или utf8_decode можно использовать для ввода некоторого кода sql, или некоторые простые примеры, такие как 1' OR 1 -- которые можно использовать, когда есть простой, где это необходимо.

Однако после небольшого исследования кажется, что очень сложно что-то вводить в простой запрос с использованием добавок или mysql_real_escape, если кодировка UTF-8 и, допустим, это самый распространенный сценарий.

Итак, учитывая этот сценарий для новичков, PLS предоставляет SQL-инъекцию POC (помните кодировку UTF-8)

 $mysql['username'] = addslashes($_POST['username']); $mysql['password'] = addslashes($_POST['password']); $sql = "SELECT * FROM users WHERE username = '{$mysql['username']}' AND password = '{$mysql['password']}'"; 

Обновление – мне просто нужен простой пример, а не полное раскрытие процесса. Даже ссылка из Google может работать.

Обновление 2 :

После дальнейших исследований версии MySQL до 5.0.77 могут быть уязвимы для проблемы GBK в сочетании с SET NAMES . Ранее считалось, что только 5.0.22 и ранее были уязвимы.

Это означает, что если вы используете версии PHP до 5.2, в которых были введены mysql_set_charset / mysqli_set_charset , ваш код может быть уязвим в определенных, хорошо продуманных условиях.

Если вы застряли на PHP 5.1, убедитесь, что вы используете MySQL 5.0.77 или новее. 5.0.77 «всего лишь» два года, но он был помещен в хранилища для RHEL / CentOS 5.x, более популярный дистрибутив застрял с версией 5.0.x серии MySQL и 5.1.x PHP.

Обновляй, люди!


Обновление 1 : Еще один недавний вопрос раскрыл источник дела GBK: Исправление в MySQL 5.0.22 . Версии ранее, чем это, сильно уязвимы при использовании чего-либо, кроме mysql_real_escape_string сочетании с mysql_set_charset а не только SET NAMES . Экземпляра mysqli называется mysqli_set_charset .

В PDO не существует эквивалента mysql_set_charset . Это может быть либо из-за того, что он может использовать подготовленные операторы MySQL, которые могут быть защищены от проблемы, либо существует ли SET NAMES для того, чтобы их основной механизм экранирования работал так, как ожидалось.

Независимо от того, используете ли вы какую-либо версию MySQL до 5.0.22 5.0.77 и не берете на себя особую осторожность, чтобы убедиться, что вы только передаете строки в известном наборе символов , вы можете оказаться открытыми для атаки.

Я оставляю остальную часть своего оригинального сообщения без изменений, но я обновил tldr.


Существует много разговоров о том, как функции addlashes и mysql_real_escape небезопасны для предотвращения инъекций

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

Если вы застряли в гетто доисторического куска дерьма, известного как расширение «mysql» (вместо использования PDO или mysqli), mysql_real_escape_string – это лучшая защита, которую вы получили, когда вам нужно объединить некоторые SQL.

Я знаю, что есть некоторые конкретные сценарии при использовании кодировки GBK, или utf8_decode можно использовать для ввода некоторого кода sql

Вероятно, вы думаете о создании некорректных последовательностей UTF-8, однако я только видел это как механизм XSS , а не механизм SQL-инъекций. Запуск строк через iconv с помощью //IGNORE//TRANSLIT должен быть достаточно хорошей защитой (обычно путем обрезания строки в точке плохой последовательности, которая является приемлемым режимом отказа при атаке – неверные последовательности никогда не должны происходить в законные запросы).

Кроме того, несмотря на то, что в нелатинских языках есть много символов «цитат», MySQL довольно приличный, только по-настоящему подчиняясь обратному коду и двойной кавычки для идентификаторов и одинарной кавычки для строковых значений.

Думая об этом больше, возможно, есть некоторая последовательность символов в другом наборе символов, которая может включать в себя одиночную цитату посередине, если принимать ее как другой набор символов. Тем не менее, очень вероятно, что addslashes полностью не знает набор символов и просто работает с необработанными байтами. Он будет придерживаться обратной косой черты в середине последовательности и взорвать ее. Тем не менее, это должно просто привести к тому, что где-то вдоль линии звучит скудная информация о наборе символов.

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

В конечном счете, если вы считаете, что это проблема, вы несете ответственность за то, чтобы вы принимали вход только в ожидаемых наборах символов и преобразовывали все входные данные в нужный набор символов, если есть несоответствие. Это редко случается, если вы когда-либо совершаете законный запрос.


tl; dr: Не беспокойтесь, если вы используете действительно старую версию MySQL и / или не удостоверяетесь, что ваши данные находятся в хорошо знакомом наборе символов. Всегда используйте механизмы эвакуации с конкретными базами данных для максимальной безопасности и всегда предполагайте, что пользователь не хочет вас видеть.