Действительно ли mysql_real_escape_string () ПОЛНОСТЬЮ защищает от SQL-инъекции?

На http://www.justinshattuck.com/2007/01/18/mysql-injection-cheat-sheet/?akst_action=share – это раздел, в котором утверждается, что вы можете обойти mysql_real_escape_string с некоторыми азиатскими кодировками символов

Обход mysql_real_escape_string () с BIG5 или GBK

"инъекционная строка"
に 関 す る 追加 情報:

вышеупомянутые символы – китайский Big5

Это правда? И если да, как бы вы защитили свой сайт от этого, если у вас не было доступа к подготовленным заявлениям?

По словам Стефана Эссера, « mysql_real_escape_string() [is] небезопасно, когда используется SET NAMES ».

Его объяснение, из его блога :

SET NAMES обычно используется для переключения кодировки с того, что по умолчанию соответствует потребностям приложения. Это делается так, что mysql_real_escape_string не знает об этом. Это означает, что если вы переключитесь на несколько многобайтовых кодировок, которые позволяют обратную косую черту как 2-й 3-й 4-й … байт, вы столкнулись с проблемой, потому что mysql_real_escape_string не работает корректно. UTF-8 безопасен …

Безопасный способ изменения кодировки – mysql_set_charset , но это доступно только в новых версиях PHP

Однако он упоминает, что UTF-8 безопасен.

Это ошибка сервера MySQL, которая, как сообщается, была исправлена ​​еще в мае 2006 года.

Видеть:

  • Ошибка MySQL # 8303 : строковые литералы с многобайтовыми символами, содержащие \, неправильно лексируются
  • Ошибка MySQL # 8317 : набор символов в запросе не может переопределить набор символов соединения
  • MySQL Bug # 8378 : Строка неправильно экранирована с набором символов клиента 'gbk'
  • MySQL 5.1.11 журнал изменений .

Сообщалось об ошибке в MySQL 4.1.20, 5.0.22, 5.1.11.

Если вы используете 4.1.x, 5.0.x или 5.1.x, убедитесь, что вы обновили хотя бы до младших номеров ревизий.

В качестве обходного пути вы также можете включить режим SQL NO_BACKSLASH_ESCAPES который отключает обратную косую черту как символ escape-котировки.

Я уверен, что это не сработает, если вы используете SQL для изменения кодировки.

Как показали другие, mysql_real_escape_string() можно обойти в неясных краевых случаях . Это одна из известных стратегий обхода логики ускользания, но могут быть другие неизвестные уязвимости, которые еще не были обнаружены.

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

Подготовленные утверждения, когда они фактически используются и не эмулируются драйвером PDO, являются надежными (по крайней мере, в отношении SQL-инъекций), поскольку они решают фундаментальную проблему с безопасностью приложений: они отделяют данные от инструкций, которые работают с данными. Они отправляются отдельными пакетами; параметризованные значения никогда не имеют возможности портить строку запроса.

Это 2015 год. Больше не убегай и не конкатенируйся. Вы все равно должны проверять свои входы в соответствии с логикой приложения (и бизнеса), но просто используйте подготовленные операторы.