Действительно ли mysql_real_escape_string() ПОЛНОСТЬЮ защищает от SQL-инъекции?
В http://www.justinshattuck.com/2007/01/18/mysql-injection-cheat-sheet/?akst_action=share-this существует раздел, в котором утверждается, что вы можете обойти mysql_real_escape_string с некоторыми кодировками азиатских символов
Обход mysql_real_escape_string() с BIG5 или GBK
"строка впрыска"
に 関 す る 追加 情報:
вышеупомянутые символы китайские Big5
Это правда? И если да, как бы вы защитили свой сайт от этого, если у вас не было доступа к подготовленным заявлениям?
Ответы
Ответ 1
По словам Стефана Эссера, "mysql_real_escape_string()
[is] небезопасно, когда используется SET NAMES
.
Его объяснение, из его блога:
SET NAMES обычно используется для переключения кодировки с того, что по умолчанию используется для приложения. Это делается таким образом, что mysql_real_escape_string
не знает об этом. Это означает, что если вы переключитесь на некоторую многобайтную кодировку, которая позволяет обратную косую черту как второй 3-й 4-й... байт, вы столкнулись с проблемой, потому что mysql_real_escape_string
не работает правильно. UTF-8 безопасен...
Безопасный способ изменения кодировки mysql_set_charset
, но доступен только в новых версиях PHP
Он упоминает, что UTF-8 безопасен, однако.
Ответ 2
Это ошибка сервера MySQL, которая, как сообщается, была исправлена еще в мае 2006 года.
См:
Исправлена ошибка в MySQL 4.1.20, 5.0.22, 5.1.11.
Если вы используете 4.1.x, 5.0.x или 5.1.x, убедитесь, что вы обновили хотя бы до младших номеров версий.
В качестве обходного пути вы также можете включить режим SQL NO_BACKSLASH_ESCAPES
, который отключает обратную косую черту как символ escape-кода.
Ответ 3
Я уверен, что это не сработает, если вы используете SQL для изменения кодировки char.
Ответ 4
Как показали другие, mysql_real_escape_string()
можно обойти в неясных краевых случаях. Эта известная стратегия обхода логики ускользания, но могут быть другие неизвестные уязвимости, которые еще не были обнаружены.
Простым и эффективным способом предотвратить SQL-инъекцию в PHP является использование подготовленных операторов, где вы можете, и очень строгий белый список, где вы не можете.
Подготовленные утверждения, когда они фактически используются и не эмулируются драйвером PDO, являются надежными (по крайней мере, в отношении SQL-инъекций), поскольку они решают фундаментальную проблему с безопасностью приложений: они разделяют данные из инструкций, которые работают с данными. Они отправляются отдельными пакетами; параметризованные значения никогда не имеют возможности портить строку запроса.
Это 2015. Не убегай и не конкатенируйся. Вы все равно должны проверить свои входы в соответствии с логикой приложения (и бизнеса), но просто используйте подготовленные инструкции.