Login-System mit AJAX, Sicherheitslücke?
Hans95
- javascript
0 Felix Riesterer0 Rolf B0 Camping_RIDER0 Rolf B
Hallo Leute,
ich bin neulich beim Surfen über eine ältere Website gestolpert, auf der es ein Login-System gibt, das mit AJAX arbeitet.
Sämtlicher Javascript-Quelltext ist einsehbar und in einzelne Dateien ausgelagert, die entsprechend in die Unterseiten eingebunden werden. Beim Überfliegen des Quelltextes kann man auch ersehen, dass mittels Javascript einzelnen Usern Ränge und Befugnisse zugeteilt werden, z.B. mit Admin- oder Moderatorrechten. Mich würde jetzt mal interessieren, ob es zu der Zeit, in der AJAX populärer war (imho vor ca. 10-15 Jahren), auch an Sicherheitsmechanismen gedacht wurde. Könnte man nicht einfach eine Seite auf dem eigenen Rechner bauen, sich die Skriptdateien herunterladen, anpassen und einbinden und sich so z.B. Rechte zuweisen, die man eigentlich nicht haben sollte? Oder gibt es einen Mechanismus, der gewährleistet, dass eine Datei nur Zugriff haben kann, wenn sie auf dem Server liegt (so ein bisschen wie die "Same Origin Policy")?
Ich habe nicht vor, mich dort irgendwie anzumelden oder Schindluder zu treiben, finde es aber bedenklich, falls eine so offensichtliche Lücke weiter bestehen würde. Danke für eine Info 😀
Gruß Hans
Lieber Hans95,
es ist eine Sache, für Anzeigezwecke die Berechtigungen eines Users in für JavaScript verarbeitbaren Dateien oder Strukturen bereitzustellen. Es ist aber eine andere Sache, auf der Serverseite mit Requests (AJAX oder andere) umzugehen und Berechtigungen zu prüfen.
Ja, es wäre fahrlässig, wenn man das System so aufsetzte, dass die vom Client gesandten Daten als Grundlage für Berechtigungen verwendet würden. Und es ist noch einmal eine ganz andere Sache, wenn man so in die Berechtigungen aller User Einsicht nehmen könnte. Das sollte in der Tat so nicht sein.
Ob nun AJAX im ursprünglichen Wortsinne (asynchronous JavaScript and XML) verwendet wird, oder damit nur „mit JavaScript asynchron (z.B. fetch-API)“ gemeint ist, spielt dabei keine Rolle.
Liebe Grüße
Felix Riesterer
Hallo Hans,
grundsätzlich ist es so, dass ein fetch() oder XMLHttpRequest, der in einem Script von Origin A abgesetzt wird, nur auf Ressourcen des Origin A zugreifen darf.
Das kann man mittels CORS aufweichen (Access-Control-* Header), womit der Server explizit erlauben kann, dass ein Script, das auf einer Seite ausgeführt wird, auch auf Ressourcen von Origin B und C zugreifen darf.
Wenn DU jetzt eine Fake-Seite auf Origin F baust und dort eigene Scripte hast, die im Hintergrund auf Origin A zugreifen und dort Schabernack treiben, hast Du es in der Hand, diesen Zugriff per CORS zu gestatten.
Weshalb es zwingend notwendig ist, Berechtigungen auch Serverseitig zu überprüfen. Ein Login darf nicht nur clientseitig erfolgen, es muss auch mit dem Server abgeglichen werden, und nur, wenn der Server den Login bestätigt und eine Session-ID (oder ein Authentication-Token oder was weiß ich was sonst) darf der Client weitermachen. Server-Requests benötigen dieses Token und der Server muss stets prüfen, ob die Aktion, die mit diesem Token ausgeführt werden soll, dem Besitzer dieses Tokens auch gestattet ist.
Natürlich kann man clientseitig ebenfalls Berechtigungen verwalten, um einem Benutzer keine Funktionen anzubieten, die sie eh nicht ausführen darf. Das ist aber letztlich eine Komfort-Funktion und nicht die eigentliche Security-Hürde.
Ich nehme an, dass die ersten naiven Ajax-Seiten das nicht beachtet haben. Die richtigen Vordenker werden sicherlich dazu etwas gesagt haben, aber Hobbyentwickler, die das dann begeistert selbst eingebaut haben, dürften etliche Löcher gelassen haben. Die damaligen Browser hatten auch noch keine Idee von Cross-Site Scripting und CORS-Headern. Dementsprechend gab es genug Schindluder. Das hat sich erst im Laufe der Jahre entwickelt und immer weiter verschärft.
Rolf
Aloha ;)
grundsätzlich ist es so, dass ein fetch() oder XMLHttpRequest, der in einem Script von Origin A abgesetzt wird, nur auf Ressourcen des Origin A zugreifen darf.
Das kann man mittels CORS aufweichen (Access-Control-* Header), womit der Server explizit erlauben kann, dass ein Script, das auf einer Seite ausgeführt wird, auch auf Ressourcen von Origin B und C zugreifen darf.
Wenn DU jetzt eine Fake-Seite auf Origin F baust und dort eigene Scripte hast, die im Hintergrund auf Origin A zugreifen und dort Schabernack treiben, hast Du es in der Hand, diesen Zugriff per CORS zu gestatten.
Moment, widersprichst du dir da nicht selbst? Müsste man nicht Zugriff auf Origin A haben, um diesen Zugriff per CORS zu gestatten? Demnach wäre ja dann nur, weil ich die Kontrolle über Origin F habe noch lange kein Zugriff auf Origin A möglich (vorausgesetzt die SOP ist dort korrekt und sinnvoll eingerichtet).
Ich sehe da allerdings ein ganz anderes viel schwerwiegenderes Sicherheitsproblem: SOP und CORS sind Konzepte, die ausschließlich vom Browser umgesetzt werden. Baue ich mir meinen eigenen Pseudo-Browser, der HTTP(S)-Requests absetzt und diese Sicherheitsmaßnahmen nicht implementiert, kann ich da jederzeit drauf pfeifen und fröhlich Daten an Origin A schicken, egal was SOP/CORS dazu sagen.
Und deshalb zur ursprünglichen Frage @OP: Nein, meines Wissens nach hat der Server keine technische Möglichkeit, den Ursprung eines Requests zu verifizieren - außer eben durch das Voraussetzen eines gemeinsamen Secrets zur Authentifizierung wie von Rolf auch hier beschrieben:
Server-Requests benötigen dieses Token und der Server muss stets prüfen, ob die Aktion, die mit diesem Token ausgeführt werden soll, dem Besitzer dieses Tokens auch gestattet ist.
Grüße,
RIDER
Hallo Janosch,
Moment, widersprichst du dir da nicht selbst?
Möglich. Ich versuche verzweifelt, CORS zu verstehen, und immer wenn ich glaube, es verstanden zu haben, sagt mir jemand "Neeeein - so doch nicht...".
Insbesondere die Rollen der beteiligten Server - welcher Server muss was schicken - drehen sich in meinem Kopf ständig auf links…
Rolf