Obwohl auf meinen Thread keine Antwort kam, denke ich, dass doch trotzdem (vor allem bei Anfängern) Bedarf besteht. Aus diesem Grund hab ich diesen Beitrag vorbereitet.
Wenn es um die Sicherung von Webseiten geht, sollte man grundsätzlich von einer Annahme ausgehen:
Der Benutzer ist böse. Wo er Daten eingeben kann, wird er versuchen, eine Lücke zu entdecken.
Man sollte sich niemals darauf verlassen, dass der Benutzer nicht weiß, wie man Sicherheitslücken ausnutzt, deswegen lässt man diese am besten gar nicht entstehen. Hier will ich ein paar der häufigsten Probleme beleuchten.
Inhaltsverzeichnis
- register_globals/import_request_variables()
- XSS/CSRF
- SQL Injection
- Remote/Local File Inclusion
- eval(), Systembefehle, SSI (Server Side Includes)
- Ungehashte Passwörter
- Allgemeines
1. register_globals/import_request_variables()
Die Server-Einstellung register_globals erlaubt es, in Formularen oder per URL übergebene Werte direkt im Script zu verwenden. Ein Wert, der z.B. in der URL http://example.com/index.php?id=4 id heißt, wäre im Script direkt als $id verfügbar.
Was passiert nun aber, wenn wir folgendes Script admin.php haben?
<?php
if (user_is_admin())
{$admin=1;}
if ($admin==1)
{
//adminoberfläche anzeigen
}
else
{
echo "Fehler! Du bist nicht der richtige Benutzer!";
}
?>
Alles anzeigen
und ein Angreifer die URL http://example.com/admin.php?admin=1 aufruft? Dann wird der Wert von admin in $admin reingeschrieben und der Benutzer hat freien Zugriff auf die Adminoberfläche. Man sollte deswegen register_globals auf dem Server deaktivieren. Die Zeile
sollte in jedes Script ganz oben eingesetzt werden, wenn register_globals an ist. Dies kann mit phpinfo() überprüft werden.
Ein ähnliches Verhalten wie register_globals ermöglicht die Funktion import_request_variables(). Aus den gleichen Gründen wie register_globals sollte man sie nicht verwenden.
2. XSS/CSRF
Die Idee beim Cross-Site Scripting (XSS) ist, den Benutzer bösartigen Javascript-Code ausführen zu lassen, der im schlimmsten Fall seine Cookies klaut. Ich weiß nicht, inwiefern ich hier das genaue Vorgehen erklären darf, deshalb lass ich es lieber.
Der Angreifer will ein <script> Tag einbringen, das auf Userseite ausgeführt wird. Das trivialste Beispiel wäre folgendes Fehlerscript error.php:
Der Programmierer hat ein anderes Script erstellt,
das im Fehlerfalle auf error.php?message=Fehlende%20Rechte umleitet. error.php gibt erwartungsgemäß
ZitatFehlende Rechte
aus. Was ist nun, wenn ein Angreifer einen Link zu
error.php?message=<script>alert('xss')</script> vorbereitet und an seine Opfer verschickt? Dann ist die Ausgabe
Zitat<script>alert('xss')</script>
Das Javascript wird auf der Seite des Users ausgeführt.
CSRF (Cross-Site Request Forgery) kann unter Umständen mit XSS kombiniert sein. Das Ziel ist zum Beispiel, einen Admin eine bestimmte Aktion ausführen zu lassen, indem dieser einen Link anklickt.
3. SQL Injection
The User hat in seinem Lexikon-Eintrag schon ziemlich alles, was man als Entwickler wissen sollte, aufgeführt.
Es wäre noch zu erwähnen, dass eine SQL-Injektion auch möglich ist, wenn man vom Benutzer eine Eingabe für ORDER BY erwartet, wie in diesem Beispiel:
//topliste ausgeben
$sql="SELECT username, level, ruhm, gold FROM usertable ORDER BY $order DESC LIMIT 50"
Man sollte deshalb prüfen, ob $order in der Liste der auszuwählenden Felder ist.
Zusätzliche Informationen würden nur darüber gehen, wie man SQL Injections ausführt, und das gehört hier nicht hin
4. Remote/Local File Inclusion
Die Kurzfassung ist: Man sollte keine Dateien inkludieren oder ihre Inhalte ausgeben, wenn der Benutzer einen Teil des Pfads selber übergeben kann. So wäre es einem Angreifer zum Beispiel möglich, Dateien, die auf seinem Webspace liegen, einzubinden, oder Inhalte von Dateien, die auf dem Server liegen (.htaccess und ähnliches) auszulesen.
5. Man sollte fast absolut nie Benutzereingaben in solche Befehle wie eval(), system() oder sonstige einfügen, da dies immer ein Sicherheitsrisiko darstellt. Auch Server Side Includes, wenn man denn welche verwendet, sollten keine Benutzereingaben direkt verwenden.
6. Siehe: Hashing.
7. Allgemeines
Zu beachten ist, dass diese möglichen Sicherheitslücken untereinander kombiniert werden könnten. So könnte zum Beispiel ein Angreifer in mySQL zuerst einen Fehler erzeugen und wenn ihm dann seine fehlerhafte Query ausgegeben wird, XSS einschmuggeln.
Außerdem gelten die Hinweise hier sowohl für Daten, die über GET, also über die URL übergeben werden, als auch über POST. Ein Angriff über letzteres ist zwar meist kompliziert, aber definitiv nicht unmöglich.
Manche neueren Webseiten verwenden URLs wie http://example.com/users/Afrael. Intern wird dabei das Script http://example.com/user.php?username=Afrael aufgerufen. Auch hier könnte man die beschriebenen Methoden anwenden, die URLs stellen also keine Sicherheitsmaßnahme, sondern allenfalls eine Bequemlichkeit für den User dar.
Zuletzt ist noch von der Ausgabe von $_SERVER['PHP_SELF'] im Script abzuraten. Wird die URL nämlich manipuliert, ist XSS möglich.
Anmerkungen, Ergänzungen usw bitte hier rein.
Edit 1: Eine weitere Möglichkeit der Validierung, die ich vergessen habe zu erwähnen, sind Reguläre Ausdrücke. Wer sich darüber informieren will, kann im Internet nach RegExp oder regular expressions suchen. Zu beachten ist jedoch, dass diese meistens relativ langsam ausgeführt werden.