PHP, что происходит, когда строка удваивается mysqli_real_escape_string - PullRequest
0 голосов
/ 14 января 2010

Я использую mysqli.

Когда я эхом mysqli_real_escape_string($db,mysqli_real_escape_string($db,'"'));

какой из них будет выходным: 1. \" 2. \\\"

Есть ли безопасный способ проверить, не экранирована ли уже строка?

К сожалению, в настоящее время я не могу тестировать, поскольку не могу получить доступ к MySQL в течение 24 часов.

Ответы [ 6 ]

7 голосов
/ 14 января 2010

Вывод \\\" (ваш второй пример).

Не думаю, что вы можете достоверно сказать, была ли строка уже экранирована или нет, вы должны организовать свой код так, чтобы вы могли вызывать mysqli_real_escape_string() только один раз.

3 голосов
/ 14 января 2010

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

2 голосов
/ 14 января 2010

Полученная строка будет \\\" (экранируя каждый из двух символов).

Если под «безопасным» вы подразумеваете «надежный», то нет. Даже если вы проверяете, что соответствующие символы экранированы, вы не можете знать, было ли это , предполагается , чтобы быть \", и строки не предоставляют никаких скрытых флагов, которые могут быть установлены, чтобы пометить его как имеющий сбежал.

Однако вам не следует вручную вызывать mysqli_real_escape_string дважды. Делайте это только в тот момент, когда вам это нужно.

Основным источником "двойного побега" является то, что вы делаете правильные вещи, убегая, но не отключайте магические кавычки и не удаляйте их, если они включены.

* Ну, как можно ближе, без использования параметризованных запросов.

1 голос
/ 16 января 2010

Многократный вызов mysqli_real_escape_string () не делает запрос менее безопасным. Однако это портит ваши данные. Хорошим примером является Конан О'Брайен.

Если вы делаете следующее:

$name=mysqli_real_escape_string($db,mysqli_real_escape_string($db,"Conan O'Brien"));
//At this point $name is Conan O\\\'Brien
mysql_query("insert into table (name)values('$name')")
//In the database the name will be stored as: Conan O\'Brien  Which is corrupt.   

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

funciton strip_all($var){
    $len=strlen($var);
    $ret=stripslashes($var);
    while($len!=strlen($ret)){
        $len=strlen($ret);
        $ret=stripslashes($ret);
    }
    return ret;
}
//$name is unkown somthing like: Conan O\\\\\\\'Brien
$name=strip_all($name);
//$name is: Conan O'Brien
$name=mysqli_real_escape_string($db,$name);
//$name is: Conan O\'Brien,  which is properly escaped.
mysql_query("insert into table (name)values('$name')")
//In the database the value is Conan O'Brien,  mysql will eat the back slash. 

Лучший подход - отслеживать, откуда исходит ваше спасение. В этом случае мы учитываем, если magic_quotes отключен или включен, а затем мы используем mysqli_real_escape_string (), который обеспечивает лучшую безопасность, поскольку экранирует больше символов.

if(get_magic_quotes_gpc())
{
   $name=stripslashes($_GET[name]);
}
$name=mysqli_real_escape_string($db,$_GET[name]);
//At this point $name is Conan O\'Brien
mysql_query("insert into table (name)values('$name')")
1 голос
/ 14 января 2010

Второй будет возвращен. " сначала будет преобразовано в \" (экранирование "), а затем преобразовано в \\\" (экранирование \ и ").

В общем, вы должны сделать это самостоятельно. Хотя есть «особенность» Магические кавычки , которая добавляет обратную косую черту к персонажу ', ", \ и символу NULL во входящих данных, Волшебные кавычки являются ужасным изобретением и будут быть удаленным в PHP 6. Более того, они могут быть включены на одном сервере и отключены на другом. Так что это даже не надежно.

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

0 голосов
/ 15 января 2010

Для добавления дополнительной информации.

Экранирование - это способ добавить дополнительную информацию в последовательность символов без введения дополнительных символов. Для этого, по крайней мере, один символ должен функционировать как символ «escape». Это означает, что исходная роль потеряна и должна быть добавлена ​​с помощью escape-последовательности.

Пример:

У нас есть язык с 3 символами: a, b и c. В котором символы имеют следующие функции:

Language 1
a has the function A
b has the function B
c has the function C

Теперь нам нужно ввести функции D и E, но мы не можем добавлять дополнительные символы.

Таким образом, мы можем сделать это с помощью escape-символа:

Language 2
a, is now the escape symbol.
aa has the function A
ab had the function D
ac has the function E
b  has the function B
c  has the function C

Последовательность aabcabac, если интерпретируется с использованием языка 1, читается как AABCABAC. Но интерпретируется с использованием языка 2 читает ABCDE.

Проблема в том, что в большинстве случаев вы не можете определить язык, используемый по символам. Эту метаинформацию необходимо предоставить до обработки данных.

Суть в том, что у вас нет безопасного способа определить, достаточно ли экранирована строка.

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