Ответ 1
Обновление 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 и не проявляете особой осторожности, чтобы убедиться, что вы только передаете строки в известном набор символов, вы можете быть открыты для атаки.
Я оставляю остальную часть своего оригинального сообщения без изменений, но я обновил TL;DR.
Существует много разговоров о том, как функции 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 и/или не уверены, что ваши данные находятся в хорошо знакомом наборе символов. Всегда используйте механизмы эвакуации с конкретными базами данных для максимального обеспечения безопасности и всегда предполагайте, что пользователь не хочет вас видеть.