Einführung
Eines der großen Sicherheits-Features, die phpBB 3.0 bietet, ist die Funktion für die Verarbeitung von Benutzereingaben, request_var. Diese Funktion wurde entwickelt, um einfach und sicher vom Benutzer eingegebene Daten abzurufen(zu verarbeiten.
Eine der wichtigsten Sicherheitsfunktionen in einem System, das externe Daten verarbeitet, ist es XSS und SQL-Injection-Angriffe im Ansatz zu stoppen. request_var macht genau dieses (mit Einschränkungen, die wir weiter unten noch erarbeiten werden).
Aus diesem Grund wurde die Anleitung erstellt wie request_var funktioniert und warum man es verwenden sollte.
SQL Injections
SQL Injections sind eine der gefährlichsten Sicherheitslücken die Web-Anwendung haben können, sie sind jedoch relativ einfach zu verhindern. Diese Angriffe sind immer dann erfolgreich, wenn Daten in die Datenbank gelangen, ohne dass sie zuvor korrekt bereinigt wurden. Alle Benutzereingaben die aus den $ _GET, $ _POST, $ _COOKIE und $ _SERVER Arrays kommen müssen korrekt bereinigt werden.
Um SQL Injections in phpBB 3.0 zu vermeiden, ist die richtige Anwendung der Typisierung von request_var erforderlich.
Daten Eingabe und Typisierung
Um SQL Injections in nicht String Typen (int) zu verhindern, ist es wichtig den richtigen Datentyp bereits während der Eingabe zu setzen. Es ist absolut entscheidend, sicherzustellen dass der Typ angegeben ist, der auch erwartet wurde.
In request_var, geschieht dies durch das setzen des zweiten Arguments, dem default Wert, der von dir benötigt wird.
Beispiel zur Nutzung von request_var
Hier ein Beispiel für die Verwendung von request_var. Das Beispiel enthält Benutzereingaben bei Verwendung von request_var und startet eine SQL-Abfrage darauf basierend. Beachte die 0 in der request_var Verwendung, diese stellt sicher, dass $user_id eine Zahl (int) ist.
Code: Alles auswählen
$user_id = request_var('user_id', 0);
$sql = 'SELECT username
FROM ' . USERS_TABLE . '
WHERE user_id = ' . $user_id;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
echo $row['username'];
Was dabei schief gehen kann
Hier ein Beispiel für einen Fehler, der sehr böse Folgen haben kann. Das Beispiel basiert auf dem vorherigen Beispiel. Anstelle des default Wertes 0, nutzen wir die user_id des aktuellen Benutzers als Standard.
Code: Alles auswählen
$user_id = request_var('user_id', $user->data['user_id']);
$sql = 'SELECT username
FROM ' . USERS_TABLE . '
WHERE user_id = ' . $user_id;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
echo $row['username'];
Die Sicherheitslücke
Hast du es bemerkt? $user->data['user_id'] ist ein Wert, der direkt aus der Datenbank stammt und alle Werte aus der Datenbank sind Zeichenketten (Strings). Dies bedeutet, $user_id wird nicht in einen Integer Wert (Zahl) umgewandelt, sondern in einen String (Zeichenkette). Die Folge ist, dass ein Angreifer die SQL-Abfrage für den eigenen Gebrauch ändern und an die Datenbank senden kann.
Wenn ein Angreifer zum Beispiel eine E-Mail-Adresse auslesen möchte, müsste er einfach nur den GET-Parameter für user_id folgendermaßen ändern:
Code: Alles auswählen
0 UNION SELECT user_email as username FROM phpbb_users WHERE user_id = 2
Code: Alles auswählen
SELECT username FROM phpbb_users WHERE user_id = 0 UNION SELECT user_email as username FROM phpbb_users WHERE user_id = 2
Wie man es richtig macht
Es ist extrem einfach, sich vor solchen Angriffen zu schützen. Es ist lediglich nötig, das zweite Argument von request_var als integer (Zahl) zu setzen.
Im Code würde dies wie folgt aussehen:
Code: Alles auswählen
$user_id = request_var('user_id', (int) $user->data['user_id']);
Noch eine Anmerkung zu Strings
Obwohl request_var, bei bestimmungsgemäßer Verwendung, in der Lage ist dich gegen die meisten Arten solcher Angriffe zu schützen, gibt es noch eine weitere Bedingung, wenn eine Zeichenfolge (String) angefordert/abgefragt wird.
Diese Bedingung, besteht darin die String - Daten (Zeichenketten) korrekt für die Datenbank zu escapen. Dazu verwendet man die sql_escape function im database object wie folgt:
Code: Alles auswählen
$foo = request_var('foo', 'bar');
$sql = 'SELECT username
FROM ' . USERS_TABLE . '
WHERE foo = ' . $db->sql_escape($foo);
Das war es!
request_var ist ein großartiges Tool, es muss aber auch ordnungsgemäß verwendet werden, das Casting (setzen) der Standardwerte auf den richtigen Typ und das escapen von Strings ist elementar, bevor du sie in einer SQL-Abfrage abschickst.
Dieser Artikel basiert auf dem Artikel des phpbb.com - blogs
Weitere Quellen: