Exterminans
Neu angemeldet
- Registriert
- 14 Juli 2013
- Beiträge
- 147
Das Loginscript ist so NICHT sicher.
Bzw. das Script an sich ist soweit sicher, als dass in der Fassung von accC zu mindestens SQL-Injections ausgeschlossen sind, aber das Script ist so nicht funktional.
Was hindert mich daran, als Außenstehenden direkt die URL "https://meineseite.de/intern/index.php" auf zu rufen?
Effektiv nichts.
Wenn der User eingeloggt ist, dann hinterlege in der Session einen Schlüssel der einen Wert ungleich false/0/null/"" hat (sprich nicht nach false evaluiert) und überprüfe in jedem gesicherten Script ob dieses Flag bereits gesetzt ist.
Ist das Flag nicht gesetzt, so musst du den Benutzer auf die Login-Maske weiterleiten und das Script per exit() terminieren. Diese Logik packst du am besten in ein separates Script, und includierst dieses am Anfang jeder zu sichernden Datei mit dem Befehl require_once(). Dieser Befehl sorgt dafür, dass das Script nur genau ein einziges mal includiert wird und sollte das Script nicht auffindbar sein, so terminiert PHP mit einem Fehler. ( include_once() hingegen wirft nur eine Warnung und PHP läuft weiter.)
Für einen Logout kannst du entweder die Session zerstören oder einfach das Flag entfernen.
In einer modernen Webanwendung hättest du typischerweise nur noch ein einzige PHP-Datei die überhaupt direkt zugänglich ist und könntest diesen Test damit einmalig schreiben und er wäre universell gültig, aber in deinem Fall musst du jede PHP-Datei die direkt über eine URL angesprochen werden kann entsprechend absichern.
PS: Die Erklärung von accC ist nicht ganz zutreffend. Ausgerechnet sein Beispiel funktioniert so nicht. Die Anweisung mysql_query() führt nur einen einzigen Query aus, auch wenn mehrere Querys per ; verknüpft wurden. Die Schwierigkeit ist jedoch eine andere, und zwar könnte der User als Namen einfach folgendes angeben:
Das ist so kurz wie effektiv und quasi der Generalschlüssel für deine Anwendung.
Schlimmeres ist in diesem speziellen Fall nicht möglich, du führst nur einen SELECT aus und verarbeitest die Daten anschließend nicht weiter. Allerdings schaut dies anders aus, wenn du die aus der Datenbank extrahierten Daten in irgendeiner Form ausgibst. Über die UNION-Klausel kann ein Angreifer in so einem Fall beliebige Daten aus anderen Tabellen holen und diese zusammen mit den Original-Daten ausgeben lassen, das könnten z.B. die Emailadressen und Passworthashes aller User sein. Innerhalb eines UPDATE-Befehles kann der User sogar noch deutlich mehr Schaden anrichten...
Bzw. das Script an sich ist soweit sicher, als dass in der Fassung von accC zu mindestens SQL-Injections ausgeschlossen sind, aber das Script ist so nicht funktional.
Was hindert mich daran, als Außenstehenden direkt die URL "https://meineseite.de/intern/index.php" auf zu rufen?
Effektiv nichts.
Wenn der User eingeloggt ist, dann hinterlege in der Session einen Schlüssel der einen Wert ungleich false/0/null/"" hat (sprich nicht nach false evaluiert) und überprüfe in jedem gesicherten Script ob dieses Flag bereits gesetzt ist.
Ist das Flag nicht gesetzt, so musst du den Benutzer auf die Login-Maske weiterleiten und das Script per exit() terminieren. Diese Logik packst du am besten in ein separates Script, und includierst dieses am Anfang jeder zu sichernden Datei mit dem Befehl require_once(). Dieser Befehl sorgt dafür, dass das Script nur genau ein einziges mal includiert wird und sollte das Script nicht auffindbar sein, so terminiert PHP mit einem Fehler. ( include_once() hingegen wirft nur eine Warnung und PHP läuft weiter.)
Für einen Logout kannst du entweder die Session zerstören oder einfach das Flag entfernen.
In einer modernen Webanwendung hättest du typischerweise nur noch ein einzige PHP-Datei die überhaupt direkt zugänglich ist und könntest diesen Test damit einmalig schreiben und er wäre universell gültig, aber in deinem Fall musst du jede PHP-Datei die direkt über eine URL angesprochen werden kann entsprechend absichern.
PS: Die Erklärung von accC ist nicht ganz zutreffend. Ausgerechnet sein Beispiel funktioniert so nicht. Die Anweisung mysql_query() führt nur einen einzigen Query aus, auch wenn mehrere Querys per ; verknüpft wurden. Die Schwierigkeit ist jedoch eine andere, und zwar könnte der User als Namen einfach folgendes angeben:
Code:
' OR TRUE;
Schlimmeres ist in diesem speziellen Fall nicht möglich, du führst nur einen SELECT aus und verarbeitest die Daten anschließend nicht weiter. Allerdings schaut dies anders aus, wenn du die aus der Datenbank extrahierten Daten in irgendeiner Form ausgibst. Über die UNION-Klausel kann ein Angreifer in so einem Fall beliebige Daten aus anderen Tabellen holen und diese zusammen mit den Original-Daten ausgeben lassen, das könnten z.B. die Emailadressen und Passworthashes aller User sein. Innerhalb eines UPDATE-Befehles kann der User sogar noch deutlich mehr Schaden anrichten...