Безопасность PHP: как кодирование может быть использовано неправильно?

Из этого отличного вопроса « UTF-8 весь путь » я читал об этом:

К сожалению, вы должны проверить каждую поданную строку как действительную UTF-8, прежде чем пытаться ее сохранить или использовать в любом месте. PHP mb_check_encoding () делает трюк, но вы должны использовать его религиозно. На самом деле этого не происходит, так как вредоносные клиенты могут отправлять данные в любую кодировку, которую они хотят , и я не нашел трюка, чтобы заставить PHP сделать это для вас надежно.

Теперь я все еще изучаю причуды кодирования, и я хотел бы точно знать, что могут делать вредоносные клиенты, чтобы злоупотреблять кодировкой. Что можно достичь? Может ли кто-нибудь привести пример? Скажем, я сохраняю вход пользователя в базу данных MySQL или отправляю его по электронной почте, как пользователь может нанести вред, если я не использую функции mb_check_encoding ?

как пользователь может нанести вред, если я не использую функции mb_check_encoding?

Речь идет о чересстрочном кодировании .

Из-за неудачной причудливости дизайна UTF-8 можно создавать байтовые последовательности, которые при анализе с наивным декодером бит-упаковки приведут к тому же характеру, что и более короткая последовательность байтов – включая один символ ASCII.

Например, символ < обычно представляется в виде байта 0x3C, но может быть также представлен с использованием последовательности UTF-8 с 0xC0 0xBC (или даже более избыточных последовательностей из 3 или 4 байта).

Если вы берете этот вход и обрабатываете его в инструменте, базирующемся на Unicode-забывающем байте, тогда любой шаг обработки символов, используемый в этом инструменте, может быть уклонен. Канонический пример должен представлять 0x80 0xBC для PHP, который имеет собственные байтовые строки. Типичное использование htmlspecialchars для HTML-кодирования символа < завершится неудачно, потому что ожидаемая байтовая последовательность 0x3C отсутствует. Таким образом, вывод сценария будет по-прежнему включать в себя оверлонокодированный < , и любой браузер, читающий этот вывод, может потенциально прочитать последовательность 0x80 0xBC 0x73 0x63 0x72 0x69 0x70 0x74 как <script и hey presto! XSS.

Overlongs были запрещены, так как обратный путь и современные браузеры больше не позволяют им. Но это была настоящая проблема для IE и Opera в течение длительного времени, и нет никакой гарантии, что каждый браузер будет в порядке. И, конечно же, это только один пример: в любом месте, где байт-ориентированный инструмент обрабатывает строки Unicode, у вас потенциально возникли аналогичные проблемы. Поэтому наилучшим подходом является удаление всех перекрытий на самой ранней фазе ввода.

Похоже, это сложная атака. Проверка документов для mb_check_encoding дает заметку «Недопустимая атака кодирования». Googling «Invalid Encoding Attack» приводит некоторые интересные результаты, которые я попытаюсь объяснить.

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

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

Пример атаки, требующей полного списка каталогов в системе unix:

http://host/cgi-bin/bad.cgi?foo=..%c0%9v../bin/ls%20-al|

Вот некоторые ссылки, если вы хотите получить более подробное техническое объяснение того, что происходит в алгоритмах:

http://www.cgisecurity.com/owasp/html/ch11s03.html#id2862815

http://www.cgisecurity.com/fingerprinting-port-80-attacks-a-look-into-web-server-and-web-application-attack-signatures.html