ben78 hat geschrieben:mysql_real_escape_string()
Meine Frage - für Euch vielleicht blöde Frage - lautet, ob der zitierte Code nur Sinnvoll ist, wenn man eine Seite hat wo sich User einloggen bzw. registrieren können.
Oder ist er in Sachen Sicherheit für jede Seite gedacht, die mit MySQL in Verbindung steht.
Letztenendes kommt es nicht darauf an, wo die Daten herkommen, sondern um was für Daten es sich handelt.
Um das Problem mal etwas zu verdeutlichen, stell' dir vor, du hast folgenden PHP/SQL-Befehl:
"
select irgendwas from tabelle where benutzer='" .
$benutzer . "
'"
Unter den gewünschten Umständen, Benutzername
anton, käme da dieses raus:
select irgendwas from tabelle where benutzer='
anton'
Funktioniert.
Unter dummen Umständen, Benutzername
anton 'der barbar' wutz, sowas:
select irgendwas from tabelle where benutzer='
anton 'der barbar' wutz'
Das haut dir MySQL um die Ohren, weil die einfachen Anführungszeichen im Namen mit jenen im SQL-Befehl kollidieren. (Mit doppelten Anführungszeichen im SQL-Befehl wäre es wohlgemerkt das gleiche Problem, nur, dass der Benutzername dann für die Kollision halt doppelte Anführungszeichen enthalten muss.)
Unter unerwünschten Umständen, ein pöser Pube, der
' or ''=' eingetippt hat, sowas:
select irgendwas from tabelle where benutzer='
' or ''=''
Die Bedingung ''='' ist immer wahr, damit wird auf jeden Fall irgendein Benutzer aus der Datenbank ausgelesen. Das bedeutet, jede sonstige Bedingung und jede andere Zugriffsbeschränkung, die mit ihr erreicht werden soll, wird ausgehebelt.
Sowas nennt sich "SQL injection" und IIRC ist gerade letzte Woche wieder einmal irgendso ein Kinderportal auf diese Weise ausgehebelt worden und zigtausende Datensätze sind, ähm, auf Wanderschaft gegangen.
Kurzum: Schon aus Grund 2 möchtest du mysql_real_escape_string() (und htmlspecialchars()) immer verwenden, wenn du dir nicht hundertprozentig sicher bist, dass du keine variable Zeichenkette (htmlspecialchars(): keine Zeichenkette mit <, > oder ") übergibst, egal, ob die Daten von dir oder von der Außenwelt eingegeben wurden.
Hunderprozentig sicher kannst du dir nur sein, wenn du zum Beispiel sowas hast:
$datum = date("Ymd", $zeitstempel);
$r = mysql_query("select dings from bumms where datum=" . $datum);
$datum ist zwar eine Zeichenkette, aber da kann nichts anderes drinstehen als Zahlen, weil ihr Inhalt aus date() stammt und dem Muster Ymd (JahrMonatTag) folgt.
Grundsätzlich gilt, besser ein mysql_real_escape_string() / htmlspecialchars() zu viel als zu wenig.
Falls dir die mysql_real_escape_string()erei zu viel ist, benutze dieses statt mysql_query():
Code: Alles auswählen
function q() { // Aufruf als q("sql-befehl", daten, daten, daten, ...);
$d = func_get_args(); // Argumente dieser Funktion in Feld $d schreiben
$sql = array_shift($d); // Erstes Argument ist der SQL-Befehl
while (list($i, $v) = each($d)) { // alle weiteren sind Werte für den Befehl
if ($v !== null) { // alles, was nicht null ist, absichern
$d[$i] = '"' . mysql_real_escape_string($v) . '"';
}
else { // Wert null als null ausschreiben, ohne Anführungszeichen
$d[$i] = "null";
}
}
return mysql_query(vsprintf($sql, $d));
}
Statt
Code: Alles auswählen
mysql_query('bla="' . mysql_real_escape string($a) . '", fasel = "' . mysql_real_escape string($b) . '"')
kannst du dann
schreiben.