Dieses Tutorial beschreibt, wie man häufig gemachte Fehler in puncto Sicherheit vermeidet oder ganz umgeht:
1.) Request-Variablen vor Ausgabe "entschärfen"
2.) Keine Request-Variablen in include-Anweisungen verwenden
3.) Externe Variablen in SQL-Queries vorher escapen
4.) Zugriff auf Request-Variablen nur über $_GET und $_POST
1.) Request-Variablen vor Ausgabe "entschärfen"
Man sollte immer alle Variablen aus externen Quellen - darunter auch Request-Variablen von , oder - vor irgendeiner Ausgabe von eventuellen Schadcode befreien.
1.) Request-Variablen vor Ausgabe "entschärfen"
2.) Keine Request-Variablen in include-Anweisungen verwenden
3.) Externe Variablen in SQL-Queries vorher escapen
4.) Zugriff auf Request-Variablen nur über $_GET und $_POST
1.) Request-Variablen vor Ausgabe "entschärfen"
Man sollte immer alle Variablen aus externen Quellen - darunter auch Request-Variablen von , oder - vor irgendeiner Ausgabe von eventuellen Schadcode befreien.
Beispielsweise Konsequenz:
Es gibt einen Artikel mit einer Kommentarfunktion. Jemand schleust jetzt aber als Kommentartext keinen normalen Text ein, sondern JavaScript. Wenn diese nicht escapt werden, also unschädlich gemacht werden, dann wird bei jedem Besuch von dieser Seite JavaScript ausgeführt, der dann z.B. Viren einschleusen kann.
Entgegenwirkung:
Je nach Art der Behandlung der Variable kann man anders vorgehen.
Wenn z.B. eine Zahl übertragen werden sollte kann man mit der Funktion die Variable zu einer Zahl konvertieren.
Oder wenn man die Verwendung von HTML unterdrücken will, sollte man die Funktion verwenden, wobei man als zweiten Parameter noch das Flag ENT_QUOTES angeben sollte, da sonst nur die doppelten Anführungsstriche umgewandelt werden (und nicht die einfachen).
Außerdem ist noch die Funktion (und deren "verwandte" Funktionen) zu erwähnen, die seit PHP Version 5.2 existiert.
PHP Code:
$zahl = $_GET['zahl'];
$zahl = intval($zahl); // Jetzt wirklich eine Zahl!
$text = $_POST['text'];
$text = htmlspecialchars($text, ENT_QUOTES); // Jetzt Text ohne evtl. HTML
$text2 = filter_input(INPUT_GET, "text2", FILTER_SANITIZE_SPECIAL_CHARS);
2.) Keine Request-Variablen in -Anweisungen verwenden
Beispielsweise Konsequenz:
Es gibt eine GET-Variablen namens "tpl", die einen Dateinamen enthält, und im PHP-Skript wird diese mittels eingebunden.
Jetzt verändert jemand diese Variable so, dass im PHP-Skript eine (PHP-)Datei von einem fremden Server eingebunden und ausgeführt wird.
Diese kann jetzt z.B. alle Datenbanktabellen löschen, falls eine Datenbankverbindung besteht.
Entgegenwirkung:
Ein Whitelist-Array einführen, in dem alle erlaubten Dateinamen beinhaltet sind, und diese mit der GET-Variable vergleichen:
PHP Code:
$allowed_sites = array("main.html", "other.html", ...);
// ...
$tpl = $_GET['tpl'];
if ( !in_array( $tpl, $allowed_sites ) ) // wenn Seite nicht in Whitelist vorhanden,
$tpl = $allowed_sites[0]; // Standard nehmen
include("templates/".$tpl);
Bevor man Variablen aus externen Quellen wie aus $_POST in Queries verwendet, sollte man sie vorher escapen!
Beispielsweise Konsequenz (vgl. PHP-Manual):
Es gibt einen Login und jemand meldet sich an:
Benutzername : Mister X
Passwort : ' OR ''='
Wenn der Aufbau des MySQL-Query im PHP-Skript so ausschauen würde:
PHP Code:
$query = "SELECT * FROM users WHERE user='".$_POST['username']."' AND password='".$_POST['password']."'";
Code:
SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
Bei den meisten Datenbanksystem gibt es eine Funktion dafür, z.B. bei
PHP Code:
$data = $_GET['data'];
$data = mysql_real_escape_string($data);
$query = "...$data...";
4.) Zugriff auf Request-Variablen nur über $_GET und $_POST
Man sollte auf Request-Variablen nur über die superglobalen Arrays $_GET und $_POST zugreifen!
In älteren PHP-Versionen, wurde automatisch eine Variable mit dem Request-Namen angelegt, sofern register_globals aktiviert war.
Somit konnte man von außen den Inhalt von Variablen in gewissem Maße verändern.
Mittels dem Array $_REQUEST, das sowohl GET- als auch POST-Daten enthält, sollte man im Normalfall auch nicht auf irgendwelche Daten zugreifen, da man unter anderem sonst nicht sicherstellen kann auf welchem Wege die Daten übertragen werden. Einen Ausnahmefall stellt z.B. die Bereitstellung einer API dar.
Entgegenwirkung:
PHP Code:
$var = $_GET['var'];
$var2 = $_POST['var2'];
Falls Ihr Anregungen oder Kritiken habt, schreibt sie einfach als Kommentar!