Является ли mysql_real_escape_string () сломанным?

Некоторые люди считают, что mysql_real_escape_string() имеет некоторые недостатки и не может защитить ваш запрос даже при правильном использовании.
Приведение некоторых окаменелых статей в качестве доказательства.

Итак, возникает вопрос: mysql [i] _real escape_string () абсолютно неприемлем?
Или еще можно использовать эту функцию для создания ваших собственных подготовленных заявлений?

С пробным кодом, пожалуйста.

Из функции API API MySQL mysql_real_escape_string :

Если вам нужно изменить набор символов соединения, вы должны использовать mysql_set_character_set() вместо выполнения инструкции SET NAMES (или SET CHARACTER SET ). mysql_set_character_set() работает как SET NAMES но также влияет на набор символов, используемый mysql_real_escape_string() , который SET NAMES не делает.

Поэтому не используйте SET NAMES / SET CHARACTER SET а mysql_set_charset для PHP, чтобы изменить кодировку, поскольку это является mysql_set_character_set с mysql_set_character_set MySQL (см. Исходный код /ext/mysql/php_mysql.c ).

Тем не менее, даже с устаревшим кодом и старыми версиями сервера, уязвимость может быть запущена только в том случае, если набор символов соединения с базой данных изменяется от однобайтового, такого как Latin-1, до многобайтового, что позволяет использовать значение 0x5c (одиночная кавычка ASCII ) во втором или более позднем байте многобайтового символа.

В частности, UTF-8 не позволяет этого, в отличие от старых азиатских кодировок, таких как GBK и SJIS. Поэтому, если ваше приложение не изменяет набор символов соединения или не изменяет его только на UTF-8 или однобайтовые, такие как Latin-n, вы можете быть в безопасности от этого эксплойта.

Но лучше всего использовать новейшую версию сервера, использовать правильный интерфейс для изменения наборов символов и использовать подготовленные запросы, чтобы вы не забывали избегать вещей.

В комментариях есть ссылка на исправление в mySQL 5.0.22 (24 мая 2006 г.) , где это было рассмотрено.