bluejoke hat geschrieben:Wie solch eine Abschottung funktionieren könnte würde mich sehr interessieren.
Das Wichtigste ist, Eingaben immer zu "quoten" (wird von MySQL unterstützt und kann auch von PHP aus verwendet werden).
Sagen wir mal, die Abfrage in PHP lautet:
SELECT count(idx) FROM Kundentabelle WHERE Username LIKE '$Username' and Password like '$Password';
$Username und $Password sind die Variablen, die bei Aufruf der Webseite (z.B.
http://www.myserver.de/checklogin.php?U ... agichnicht) übergeben werden.
Die Abfrage zählt, wieviele übereinstimmende Einträge es gibt, in der Annahme, daß jeder Username nur einmal vorkommt.
Ruf ich die Seite also richtig auf (von einem Formular zur Eingabe der Benutzerdaten) und bin in der Datenbank erfasst, dann liefer die SELECT Abfrage als Ergebnis 1 zurück.
Ich bin also bekannt und darf rein.
Nun gibt es aber Wildcards in SQL (wie * bei Dateien; hier ist es %).
Ruft nun jemand diese Seite mit meinem Usernamen auf, aber verwendet als Passwort die Wildcard, dann wird der Ausdruck in PHP so extrahiert, wie hier:
SELECT count(idx) FROM Kundentabelle WHERE Username LIKE 'Max.' and Password like '%;
Das heisst soviel wie: Zähl mir die Anzahl der User "Max." mit irgendeinem Passwort... kommt auch nur 1 raus - und der Hacker ist drin.
Wird nun die Eingabe gequoted, wird das Passwort umgewandelt nach: '\%', was soviel heisst wie: exact das Zeichen "%" als Passwort.
Stimmt ja nicht, Ergebnis 0 -> kein Zutritt.
Ich denke, in der Include Datei für MySQL habe ich das Quote Kommando drinnen.
Ein anderer Punkt - hat nichts mit MySQL zu tun, sondern generell: Ein richtige Abfrage in der Art wie oben muss 1 zurückgeben. Nicht >0. 2 ist auch größer Null, aber ist nicht erlaubt (schliesslich darf jeder User nur einmal in der Datenbank vorkommen!) und somit stimmt was nicht: no go!
Also immer exakte Ergebnisse erwarten und bei Abweichungen darauf reagieren.
Was anderes; ich hasse es eigentlich, wenn Username (Nickname) und Login gleich sind. Schliesslich kann der User/Nick von jedem gesehen werden. Damit muss einer nur noch das Passwort hacken... besser den Login nur für den Login verwenden, und als Displaynamen den User was anderes wählen lassen.
Zurück zu SQL:
Sehr beliebt ist auch, Abfragen anzuhängen:
Zur Erinnerung die Abfrage von vorhin... SELECT count(idx) FROM Kundentabelle WHERE Username LIKE '$Username' AND Password LIKE '$Password';
Nun kann ja jemand auf die Idee kommen, als Password das zu verwenden:
egal' OR 1 OR '
Die Query sieht dann so aus:
SELECT count(idx) FROM Kundentabelle WHERE Username LIKE 'Max.' AND Password LIKE 'egal' OR 1 OR '';
OR 1
ist immer wahr, Abfrage also erfolgreich. Dem wird natürlich auch ein Riegel vorgeschoben, wenn gequoted wird:
'egal\' OR 1 OR \''
Aber es ist trotzdem erwähnenswert, weil ein Pöser Pursche allerhand Abfragen angehängen kann, die neben Passwortklau noch ganz andere Dinge machen; Tabellen/Datenbanken löschen, downloaden, uploaden und gelegentlich sogar aufs lokale Dateisystem zugreifen...
Also auch immer die MySQL Berechtigungen sehr restriktiv setzen! Bei PHP greift ja im Grunde nicht der Anwender auf die DB zu, sondern ein eigener Benutzer. Der sollte nie mehr dürfen, als das unbedingt notwendige!
Am Besten ist es, alle DB Einstellungen in eine PHP include Datei zu legen - und anschliessend dafür zu sorgen, dass die Datei nicht lesend geöffnet werden kann von Gott und der Welt. Große Provider achten in der Regel darauf, dass .inc Dateien nicht angezeigt werden können. Falls nicht geschehen, kann man das mit einer .htaccess Datei erreichen.
Und ein letztes: äusserst vorsichtig beim Zugriff aufs lokale Dateisystem. Sehr beliebt sind zum Beispiel Loader für Seiten...
http://www.myserver.de/load.php?seite1.htm
Häufig wird vergessen, was passiert, wenn ein (Ab)user mal kurz
http://www.myserver.de/load.php?/etc/passwd oder eine andere Datei aufruft... zwar kann man PHP sehr restriktiv installieren, aber falls das vergessen wurde, hat jemand lesenden Zugriff auf das komplette Dateisystem, u.a. auch auf die vorhin erwähnte
http://www.myserver.de/load.php?datenbank.inc
Wahrscheinlich kann man darüber wochenlang referieren... ich kratze da auch nur an der Oberfläche, aber ich denke es hilft als Denkanstoß...