db_Query_Secure()Benötigt:Code:
function db_query_secure($sql, $args) {
/**
* db_query_secure()
* Eine Wrapper für mysql_query mit Vorkehrungen gegen SQL-Injections
* Imitiert PDO::Prepare und PDO::Execute
*
* Version 1.0 vom 6. August 2008
*
* © Copyright 2008 by Basilius Sauter
* Lizenziert unter der GNU GPL in Version 2 oder neuer
* Basiert auf der Originalen Funktion db_query und dem MySQL-Wrapper
* des Engelsreiches
*/
# Verfügbarmachen einiger Variablen für die Zeitauswertung
global $dbqueriesthishit, $dbtimethishit;
# Einfügen der Argumente und maskieren derselbigen
foreach($args as $key => $value) {
# Maskieren von ? und : im Argument, sofern keine Zahl vorhanden ist
if(is_int($value) === false AND is_numeric($value) === false) {
$value = str_replace('?', '!-!QUESTION_MARK_QWERTZU!-!', $value);
$value = str_replace(':', '!-!DOUBLE_POINT_QWERTZU!-!', $value);
}
if($key == '?' OR is_numeric($key)) {
if(is_int($value) OR is_float($value)) {
# Integer und Fliesskommazahlen enthalten keine Gefährlichen Zeichen. Eine Maskierung oder das
# Setzen in Fuss-Zeichen (') nicht notwendig und kann zu verfälschenden Resultaten führen
$id = md5(mt_rand(0, 30000));
$sql = preg_replace('/\?/', ":PREREPLACE_$id", $sql, 1); # preg_replace, da str_replace keine Limitationen beherrscht
$sql = str_replace(":PREREPLACE_$id", $value, $sql);
}
else {
$value = db_real_escape_string($value); # Wrapper-Funktion für mysql_real_escape_string()
$id = md5(mt_rand(0, 30000));
$sql = preg_replace('/\?/', ":PREREPLACE_$id", $sql, 1); # preg_replace, da str_replace keine Limitationen beherrscht
$sql = str_replace(":PREREPLACE_$id", "'$value'", $sql);
}
}
elseif(substr($key, 0, 1) == ':') {
if(is_int($value) OR is_float($value)) {
# Integer und Fliesskommazahlen enthalten keine Gefährlichen Zeichen. Eine Maskierung oder das
# Setzen in Fuss-Zeichen (') nicht notwendig und kann zu verfälschenden Resultaten führen
$sql = str_replace($key, "$value", $sql);
}
else {
$value = db_real_escape_string($value); # Wrapper-Funktion für mysql_real_escape_string()
$sql = str_replace($key, "'".$value."'", $sql);
}
}
}
# Demaskieren der Platzhalter für ? und :
$sql = str_replace('!-!QUESTION_MARK_QWERTZU!-!', '?', $sql);
$sql = str_replace('!-!DOUBLE_POINT_QWERTZU!-!', ':', $sql);
# Zeitmessung für DB-Statistik
$dbqueriesthishit++;
$dbtimethishit -= getmicrotime();
# Funktionsname zusammensetzen
$fname = DBTYPE."_query";
# Schreiben in die Datenbank
$res = $fname($sql, LINK);
# Fehlerausgabe
if($res === false) {
global $session;
if($session['user']['superuser'] >= 3) {
printf("<pre>%s</pre>", HTMLSpecialchars($sql));
}
print db_error(LINK);
exit;
}
# Zeitmessung für DB-Statistik
$dbtimethishit += getmicrotime();
# Rückgabe
return $res;
}
BeschreibungPräpariert einen SQL-String mit Platzhaltern so, dass keine SQL-Injektion möglich ist. Die Funktion imitiert dabei das Verhalten von
PDO-Statements.
Als Platzhalter können dabei ? dienen. Sie werden in der Reihenfolge wie im Array angegeben ersetzt, das erste wird dabei zuerst ersetzt, die letzte Angabe als letztes. Ebenso können die Platzhalter Namen haben, das Variablenzeichen ist : (Wie in PHP $). Um :var ersetzen zu können, muss im Array ein Eintrag mit dem Schlüssel :var existieren. Alle Einträge, die einen Schlüssel haben, der mit einem : beginnt, werden nur für benannte Platzhalter verwendet - alle Einträge mit einem numerischen Schlüssel nur für die ?-Platzhalter.
Integer und Fliesskommazahlen werden nicht maskiert und ohne Fuss-Striche (') in den Query eingepflegt.
BeispielCode:
$args = array(
'Testeingabe mit bösen Zeichen "\' \\',
':var' => 'Testeingabe mit bösen Zeichen "\' \\',
3450.345, # Irgend eine Zahl
);
db_query_secure("INSERT INTO testtable (field1, field2, field3) VALUES (?, :var, ?)", $args);
Ausgabe
Code:
INSERT INTO testtable (field1, field2, field3) VALUES ('Testeingabe mit bösen Zeichen \"\' \\', 'Testeingabe mit bösen Zeichen \"\' \\', 3450.345)