Альтернатива mysql_real_escape_string без подключения к DB

Я бы хотел, чтобы функция вела себя как 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

Ответ 1

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

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

Ответ 2

Хорошо, согласно странице 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);
}

Ответ 3

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

// 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;
}

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

Ответ 4

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

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

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

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

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

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

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

Компенсации. Если вы не можете обновить MySQL до версии, содержащей исправление ошибки в mysql_real_escape_string(), но запустите MySQL 5.0.1 или новее, вы можете использовать режим NO_BACKSLASH_ESCAPES SQL как обходной путь. (Этот режим был введен в 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.