Альтернатива mysql_real_escape_string без подключения к БД - PullRequest
84 голосов
/ 22 июля 2009

Мне бы хотелось иметь функцию, которая будет вести себя как mysql_real_escape_string без подключения к базе данных, так как иногда мне нужно проводить тестирование без подключения к базе данных. mysql_escape_string устарела и поэтому нежелательна. Некоторые из моих выводов:

http://www.gamedev.net/community/forums/topic.asp?topic_id=448909

http://w3schools.invisionzone.com/index.php?showtopic=20064

Ответы [ 4 ]

70 голосов
/ 22 июля 2009

Невозможно безопасно экранировать строку без подключения к БД. mysql_real_escape_string() и подготовленным операторам требуется соединение с базой данных, чтобы они могли экранировать строку, используя соответствующий набор символов - в противном случае атаки с использованием SQL-инъекций все еще возможны с использованием многобайтовых символов.

Если вы только тестируете , то вы также можете использовать mysql_escape_string(), это не на 100% гарантировано от атак с использованием SQL-инъекций, но невозможно создать что-то более безопасное без подключения к БД.

60 голосов
/ 22 июля 2009

Ну, согласно справочной странице функции mysql_real_escape_string : «mysql_real_escape_string () вызывает библиотечную функцию MySQL mysql_real_escape_string, которая экранирует следующие символы: \ x00, \ n, \ r, \, '," и \ x1a ".

Учитывая это, функция, указанная во второй размещенной вами ссылке, должна делать именно то, что вам нужно:

function mres($value)
{
    $search = array("\\",  "\x00", "\n",  "\r",  "'",  '"', "\x1a");
    $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z");

    return str_replace($search, $replace, $value);
}
23 голосов
/ 22 июля 2009

В противоположность моему другому ответу эта следующая функция, вероятно, безопасна, даже с многобайтовыми символами.

// replace any non-ascii character with its hex code.
function escape($value) {
    $return = '';
    for($i = 0; $i < strlen($value); ++$i) {
        $char = $value[$i];
        $ord = ord($char);
        if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
            $return .= $char;
        else
            $return .= '\\x' . dechex($ord);
    }
    return $return;
}

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

6 голосов
/ 25 июля 2009

Из дальнейших исследований я нашел:

http://dev.mysql.com/doc/refman/5.1/en/news-5-1-11.html

Исправление безопасности:

В обработке многобайтового кодирования была обнаружена дыра в безопасности SQL-инъекций. Ошибка была на сервере, неправильно обрабатывал строку, сбежавшую с помощью функции API mysql_real_escape_string () C.

Эта уязвимость была обнаружена и сообщена Джошем Беркусом и Томом Лейном в рамках межпроектного сотрудничества в области безопасности консорциума OSDB. Для получения дополнительной информации о внедрении SQL см. Следующий текст.

Обсуждение. В обработке многобайтового кодирования обнаружена дыра в безопасности внедрения SQL В дыру в безопасности SQL-инъекций может входить ситуация, когда пользователь предоставляет данные для вставки в базу данных, пользователь может вводить операторы SQL в данные, которые будет выполнять сервер. Что касается этой уязвимости, когда используется экранирование, не поддерживающее набор символов (например, addlashes () в PHP), возможно избежать обхода в некоторых многобайтовых наборах символов (например, SJIS, BIG5 и GBK). В результате такая функция, как addlashes (), не может предотвратить атаки с использованием SQL-инъекций. Это невозможно исправить на стороне сервера. Лучшее решение для приложений - использовать экранирование с учетом набора символов, предоставляемое такой функцией, как mysql_real_escape_string ().

Однако была обнаружена ошибка в том, как сервер MySQL анализирует выходные данные mysql_real_escape_string (). В результате, даже когда использовалась функция mysql_real_escape_string (), поддерживающая набор символов, внедрение SQL было возможно. Эта ошибка была исправлена.

Обходные. Если вы не можете обновить MySQL до версии, которая включает исправление ошибки в синтаксическом анализе mysql_real_escape_string (), но запустить MySQL 5.0.1 или новее, вы можете использовать режим SQL NO_BACKSLASH_ESCAPES в качестве обходного пути. (Этот режим был введен в MySQL 5.0.1.) NO_BACKSLASH_ESCAPES включает стандартный режим совместимости SQL, где обратный слеш не считается специальным символом. В результате запросы не будут выполнены.

Чтобы установить этот режим для текущего соединения, введите следующую инструкцию SQL:

SET sql_mode='NO_BACKSLASH_ESCAPES';

Вы также можете установить глобальный режим для всех клиентов:

SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';

Этот режим SQL также может быть включен автоматически при запуске сервера с помощью параметра командной строки --sql-mode = NO_BACKSLASH_ESCAPES или путем установки sql-mode = NO_BACKSLASH_ESCAPES в файле параметров сервера (например, my.cnf или my.ini, в зависимости от вашей системы). (Ошибка № 8378, CVE-2006-2753)

См. Также ошибка # 8303.

...