Двойник избегает строки неправильно? - PullRequest
3 голосов
/ 13 ноября 2010

У меня есть класс базы данных, который автоматически экранирует входные строки перед построением запроса с помощью mysqli_real_escape_string (). Но может быть так, что в сценарии строка экранируется и затем передается в класс базы данных, который снова экранирует ее. Может ли это быть неправильно? Что может случиться?

Ответы [ 6 ]

6 голосов
/ 13 ноября 2010

Поскольку у вас нет хорошего способа сообщить на другом конце (когда вы извлекаете данные из базы данных), сколько раз они были экранированы, непоследовательное двойное экранирование строки приведет кс вашими данными в ваших конечных данных, которых раньше не было - потому что вы добавите два экранирующих слоя, но только один не экранированный.

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

5 голосов
/ 13 ноября 2010

При первом проходе через mysqli_real_escape_string следующие символы экранируются путем вставки \ перед каждым из опасных символов:

NUL (ASCII 0), \ n, \ r, \, ', "и Control-Z:

NUL (chr(0)) becomes "\0" (chr(92).chr(48))
\n (chr(13)) becomes "\n" (chr(92).chr(110))
\r (chr(10)) becomes "\r" (chr(92).chr(114))
\ (chr(92)) becomes "\\" (chr(92).chr(92))
' (chr(39)) becomes "\'" (chr(92).chr(39))
" (chr(34)) becomes "\"" (chr(92).chr(34))
Control-Z (chr(26)) becomes "\Z" (chr(92).chr(90))

При втором проходе через mysqli_real_escape_string, \ снова экранируется:

"\0" (chr(92).chr(48)) becomes "\\0" (chr(92).chr(92).chr(48))
"\n" (chr(92).chr(110)) becomes "\\n" (chr(92).chr(92).chr(110))
"\r" (chr(92).chr(114)) becomes "\\r" (chr(92).chr(92).chr(114))
"\\" (chr(92).chr(92)) becomes "\\\\" (chr(92).chr(92).chr(92).chr(92))
"\'" (chr(92).chr(39)) becomes "\\'" (chr(92).chr(92).chr(39))
"\"" (chr(92).chr(34)) becomes "\\"" (chr(92).chr(92).chr(34))
"\Z" (chr(92).chr(90)) becomes "\\Z" (chr(92).chr(92).chr(90))

Двойное экранирование строк не создает какой-либо уязвимости, но оно добавляет много дополнительных символов «\» в строки, которые вы сохраняете в базе данных.

Лучший способ сделать экранирование - это: 1Отключите магические кавычки 2) Используйте запросы только с именованными параметрами и ничего не экранируйте перед передачей их в запрос. MySQL (и все остальные поставщики баз данных в этом отношении) будет правильно экранировать строки (однако вы можете столкнуться спроблема с chr (0), завершающим строку).

Если вам абсолютно необходимо использовать строковые запросы, экранируйте данные один раз и только один раз, непосредственно перед тем, как они будут вставлены в запрос. Не экранируйте всезапрос.

3 голосов
/ 13 ноября 2010

Нет ничего плохого в двойном экранировании строки, если у вас есть гарантия двойного экранирования перед использованием.

Если вы забудете дважды удалить его, то в итоге пользователь прочитает экранированную строку, что не очень приятно.

1 голос
/ 13 ноября 2010

Для MySQL используйте подготовленные операторы, и вам не нужно беспокоиться о экранировании строки на уровне базы данных.

И для PHP помните, что вы можете использовать и ", и" для построения строк. Это вы можетеиспользуйте, чтобы избежать необходимости заключать в кавычки строки. Если ваша строка начинается с «тогда вам не нужно заключать в кавычки свои».

1 голос
/ 13 ноября 2010

Да, это может быть неправильно, потому что в вашей базе данных могут быть такие вещи, как let \ 's go .

Вы избегаете SQL-инъекций или синтаксической ошибки запроса, чтобы не «преобразовывать» данные, которые вы хотите сохранить. Если вы хотите сохранить Let's в базе данных, вы должны избегать его только один раз при создании запроса. Вам не нужно «удалять» значение, полученное из базы данных. Когда вы заглядываете в свою базу данных, вы никогда не увидите значение с escape-символами.

Экранирование - реальная проблема для начинающих в PHP, возможно, это связано с функцией magic_quote (). Вы должны взглянуть на http://php.net/manual/en/security.magicquotes.php Вы не должны использовать эту функцию, это сбивает с толку. В вашем скрипте, если вы не можете изменить php.ini, чтобы отключить эту функцию, вы можете сделать это во время выполнения с помощью:

if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
    foreach ($val as $k => $v) {
        unset($process[$key][$k]);
        if (is_array($v)) {
            $process[$key][stripslashes($k)] = $v;
            $process[] = &$process[$key][stripslashes($k)];
        } else {
            $process[$key][stripslashes($k)] = stripslashes($v);
        }
    }
}
unset($process);
}

Обратите внимание, этот код взят из http://www.php.net/manual/en/security.magicquotes.disabling.php

Не торопитесь, чтобы правильно понять, как вы справляетесь с побегом, вы сэкономите много времени в будущем.

1 голос
/ 13 ноября 2010

Строка с двойным экранированием будет отображаться неправильно, если вы не учтете это.Вы, вероятно, видели примеры визуализации текста в экранированной форме (например, с дополнительной обратной косой чертой или HTML-сущностями).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...