Passwort-Reset-Links gegen Missbrauch absichern

CybersicherheitBeginner
Jetzt üben

Einführung

Das Mitgliederportal von Harbor ermöglicht die Wiederherstellung eines Kontos nach einem vergessenen Passwort. Die E-Mail enthält ein zeitweiliges Token: Sein Besitz sollte genau eine Passwortänderung für genau ein Konto erlauben. Der Support stellte fest, dass Links wiederverwendbar sind und Passwörter anderer Konten ändern können.

Du stellst zunächst ein synthetisches Konto regulär wieder her, beobachtest das unsichere Verhalten und reparierst einen kleinen Python-Handler. Python-Vorkenntnisse sind nicht nötig; Funktionen und Bedingungen werden vor der Bearbeitung erklärt. Du solltest einen Terminalbefehl eingeben und Tabs wechseln können.

Portal Web zeigt die Anwendung, Mailbox Web die simulierten E-Mails und App Server den vorbereiteten Code. Alles läuft auf dieser unabhängigen Trainingsinstanz. Es gibt keinen externen Mailversand. Token, Zeitvergleiche, Datenbanktransaktionen, Passwortänderungen und Anmeldungen sind echt; die kleine Anwendung ist kein Identitätssystem für den Produktivbetrieb.

Ein Konto regulär wiederherstellen

In diesem Schritt folgst du einer Rücksetzmail und meldest dich mit dem neuen Passwort an. So lernst du das Verhalten kennen, das die Reparatur erhalten muss.

Wähle zu Beginn dieses Schritts den Tab Portal Web in der Lab-Oberfläche aus.

Ein Konto identifiziert eine Person; ein Passwort weist ihre Anmeldeberechtigung nach. Bei einem vergessenen Passwort erlaubt ein Link vorübergehend dessen Änderung. Das Token im Link ist nicht das Passwort. Im lokalen Postfach kannst du die Eigentümer der synthetischen Konten maya und noah spielen. Beide beginnen mit StartPass42!. Verwende nur diese Trainingskonten.

Formulare in Portal Web zum Anfordern eines Links, Zurücksetzen des Passworts und Anmelden

Wechsle zum Tab Portal Web. Suche Request a reset link. Trage maya bei Recovery account ein und klicke auf Send reset link. Es erscheint Link requested. Open Local Mailbox. Wechsle zum Tab Mailbox Web. Falls ein Rücksetzformular oder eine Ergebnisseite angezeigt wird, wähle Local Mailbox, um zur Nachrichtenliste zurückzukehren. Aktualisiere die Nachrichtenliste, damit die neueste Nachricht oben erscheint. Sie nennt den Empfänger und enthält Open reset link sowie einen Tokenwert.

Mailbox Web zeigt die neue Nachricht mit dem Rücksetzlink

Verwende den Link und das Token aus deinem aktuellen Tab Mailbox Web; Tokenwerte unterscheiden sich zwischen den Umgebungen.

Klicke in dieser Nachricht auf Open reset link. Im selben Tab öffnet sich das Formular mit ausgefüllten Feldern Token und Reset account. Lasse beide unverändert, trage FirstPass42! bei New password ein und klicke auf Reset password. Erwartet werden Reset accepted und HTTP 200.

Erfolgreiches Zurücksetzen im Tab Mailbox Web

HTTP ist der Austausch von Anfragen und Antworten zwischen Browser und Server. Hier bedeutet 200 angenommen, 403 abgelehnt und 500 Anwendungsfehler. Ein Verbindungsfehler ist etwas anderes als eine Sicherheitsablehnung.

Wechsle zum Tab Portal Web. Falls das Anfrageergebnis angezeigt wird, wähle Back to portal, um die Formulare wieder zu öffnen. Nutze Sign in: Login account maya, Password FirstPass42!, dann Sign in. Erwarte Login accepted. Eine funktionierende Wiederherstellung ändert das tatsächliche Passwort, nicht bloß eine Seitenbeschriftung.

Geht ein Link verloren, fordere mit demselben Formular einen neuen an und verwende die neueste Nachricht. Links gelten 30 Minuten. Ein Tippfehler oder abgelaufener Link erfordert keinen Neustart der Umgebung.

Die fehlerhafte Grenze beobachten

In diesem Schritt unterscheidest du mit verwerfbaren Demonstrationsänderungen Eigentümer, Gültigkeitsdauer und einmalige Berechtigung eines Tokens.

Wähle zu Beginn dieses Schritts den Tab Portal Web in der Lab-Oberfläche aus.

Der Browser sendet Felder mit Namen und Werten. Benutzer können sie ändern. Der Server darf Reset account daher nicht vertrauen, nur weil die E-Mail es vorausgefüllt hat. Er speichert einen eigenen Tokendatensatz:

Feld Bedeutung
account Konto, das dieses Token verwenden darf
expires_at Letzter erlaubter Zeitpunkt, als Sekunden seit einem festen Zeitursprung
used Vor Verwendung 0, danach 1

Ein neues Token gilt nur für seinen Eigentümer und vor Ablauf. Eine erfolgreiche Rücksetzung macht es verwendet; es darf nie wieder nutzbar werden. Auch ein unbenutztes Token kann durch Zeitablauf ungültig werden. Beide ungültigen Zustände erlauben keine weitere Rücksetzung.

Wechsle zum Tab Portal Web, wähle Back to portal, falls eine Ergebnisseite angezeigt wird, und fordere einen neuen Link für maya an. Wechsle zum Tab Mailbox Web. Falls ein Rücksetzformular oder eine Ergebnisseite angezeigt wird, wähle Local Mailbox, um zur Nachrichtenliste zurückzukehren. Aktualisiere die Nachrichtenliste, öffne den neuesten Link und setze maya auf DemoPass42!. Wähle im Tab Mailbox Web auf der Ergebnisseite Local Mailbox, um zur Nachrichtenliste zurückzukehren. Öffne den Link aus derselben Nachricht erneut und setze maya auf ReplayDemo42!. Beide Anfragen zeigen Reset accepted. Die zweite müsste abgelehnt werden: Das ist ein Replay, die erneute Nutzung einer bereits verbrauchten Berechtigung.

Ein anderes Konto ausprobieren

Wähle im Tab Mailbox Web Local Mailbox und öffne denselben Nachrichtenlink nochmals. Ändere Reset account zu noah und New password zu CrossDemo42!; klicke auf Reset password. Die Anfrage wird angenommen. Wechsle zum Tab Portal Web und wähle Back to portal, um das Anmeldeformular wieder zu öffnen. Melde dich als noah mit CrossDemo42! an. Ein für maya ausgestellter Link hat noah geändert: Die Bindung zwischen Token und Konto fehlt.

Ein abgelaufenes Token ausprobieren

Bleibe im Tab Portal Web und wähle Back to portal, um dessen Rücksetzformular wieder zu öffnen. Trage expired-demo bei Token, maya bei Reset account und ExpiredDemo42! bei New password ein. Dieses vorbereitete Token lief bereits eine Stunde vor dem Einrichten ab. Klicke auf Reset password. Auch diese Anfrage wird angenommen: Der Server ignoriert die Uhr. Du musst keinen Timer abwarten, um den Fehler zu beobachten.

Diese Konten sind für verwerfbare Demonstrationen bestimmt; die Reparaturtests nutzen saubere Kopien. Behalte den beobachteten Zustand bei. Eine direkte Datenbankbearbeitung ist nicht nötig.

Das Token binden und verbrauchen

In diesem Schritt reparierst du die kleine Serverfunktion und testest sie, ohne aktive Demonstrationskonten zu ändern.

Wähle zu Beginn dieses Schritts den Tab App Server in der Lab-Oberfläche aus.

Wechsle zum Tab App Server. Er startet in /home/labex/project/reset. cat zeigt eine Textdatei; der Dateiname ist sein Argument. Lies den Handler:

Wechsle zum Tab App Server, bevor du den folgenden Befehl ausführst.

cat handler.py

Die erste Zeile importiert zwei vorbereitete Hilfsfunktionen. def definiert eine Funktion; die Namen in Klammern sind Parameter, die Eingaben eines Aufrufs. eligible(row, account, now) erhält den gespeicherten Tokendatensatz, das übermittelte Konto und die aktuelle Serverzeit. row["account"] liest ein Feld. row is None bedeutet, dass kein Token gefunden wurde. Der eingerückte if-Block läuft nur bei erfüllter Bedingung; return False verweigert, return True erteilt die Berechtigung. Vier führende Leerzeichen bilden hier einen Python-Block.

Der aktuelle Code liefert für jedes vorhandene Token True, was die drei Fehler erklärt. Außerdem ruft reset die Funktion unsafe_reset auf, die das Passwort ändert, ohne das Token zu verbrauchen.

Die Reparatur braucht alle Bedingungen zugleich. == vergleicht Werte, > bedeutet größer als und and verlangt zwei wahre Seiten. or würde eine der beiden genügen lassen, sodass eine gültige Eigenschaft eine ungültige verdeckt. Ein zukünftiger Ablaufzeitpunkt ist größer als now; Gleichheit ist bereits abgelaufen. used == 0 erlaubt nur unbenutzte Token.

consume_and_reset startet eine SQLite-Transaktion, liest das aktuelle Token, ruft deine Funktion eligible auf und schreibt Passwortänderung und used = 1 gemeinsam fest. Das ist Atomarität: Beide Änderungen gelingen zusammen. Die Sperre wird vor dem Lesen gesetzt, sodass zwei konkurrierende Anfragen nicht beide ein unbenutztes Token sehen. Du implementierst weder Sperren noch Passwort-Hashing.

Öffne die kleine Datei mit dem Terminaleditor nano:

nano handler.py

Ersetze ihren Inhalt durch diesen Code. Mit Pfeiltasten und Rücktaste/Entf kannst du alten Text entfernen und dann den vollständigen Ersatz einfügen. Behalte Leerzeichen und Zeichen exakt bei; die Klammern erlauben die mehrzeilige Bedingung.

from framework import unsafe_reset, consume_and_reset


def eligible(row, account, now):
    if row is None:
        return False
    return (row["account"] == account
            and row["expires_at"] > now
            and row["used"] == 0)


def reset(db, token, account, password):
    return consume_and_reset(db, token, account, password, eligible)

Speichere mit Ctrl+O, bestätige handler.py mit Enter und beende mit Ctrl+X. Jede Webanfrage liest den gespeicherten Handler; ein Neustart ist unnötig. Bei HTTP 500 öffne die Datei erneut und vergleiche Einrückung, Klammern und Anführungszeichen.

python3 führt ein Python-Programm aus. Der vorbereitete Prüfer erhält den Handlerpfad und startet eine getrennte HTTP-Anwendung mit temporären SQLite-Testdaten. Er testet den echten Handler, ohne ihn zu reparieren oder aktive Konten zu ändern:

python3 /opt/reset-lab/check.py handler.py

Erwarte elf PASS-Zeilen, darunter valid reset accepted, replay denied und competing use has exactly one winner. Bei unsicherem Code benennt FAIL die verletzte Eigenschaft. Alles abzulehnen lässt reguläre Rücksetzung und Anmeldung durchfallen. Browserfelder oder die aktive Datenbank zu ändern repariert keinen mit frischen Daten geprüften Code. Öffne bei Bedarf nano handler.py, korrigiere, speichere und wiederhole denselben Prüfer.

Die Wiederherstellung erneut beweisen

In diesem Schritt verwendest du den reparierten aktiven Dienst und verbindest seine Ergebnisse mit den isolierten Sicherheitstests.

Wähle zu Beginn dieses Schritts den Tab Portal Web in der Lab-Oberfläche aus.

Wechsle zum Tab Portal Web, wähle Back to portal, falls eine Ergebnisseite angezeigt wird, und fordere einen frischen Link für maya an. Wechsle zum Tab Mailbox Web. Falls ein Rücksetzformular oder eine Ergebnisseite angezeigt wird, wähle Local Mailbox, um zur Nachrichtenliste zurückzukehren. Aktualisiere die Nachrichtenliste, öffne den neuesten Link und setze maya auf ResetSafe42!. Erwarte Reset accepted und HTTP 200. Wähle im Tab Mailbox Web Local Mailbox, um zur Nachrichtenliste zurückzukehren. Öffne den Link aus derselben Nachricht erneut und versuche ReplayAgain42! für maya. Erwarte Reset denied und HTTP 403.

Nach der Reparatur des Handlers wird die erneute Verwendung des Rücksetzlinks abgelehnt

Wechsle zum Tab Portal Web, wähle Back to portal, falls eine Ergebnisseite angezeigt wird, und fordere einen weiteren frischen Link für maya an. Wechsle zum Tab Mailbox Web, wähle Local Mailbox, aktualisiere die Liste und öffne den neuesten Link. Ändere Reset account zu noah und versuche BlockedCross42!. Erwarte Reset denied. Diese Ablehnung darf den unbenutzten Link des Eigentümers nicht verbrauchen: Wähle im Tab Mailbox Web Local Mailbox und öffne dieselbe Nachricht erneut. Lasse maya unter Reset account stehen und setze ResetSafe42!. Das muss gelingen.

Abgelaufene Token ablehnen und Anmeldung erhalten

Wähle im Tab Mailbox Web Back to portal, um dessen Rücksetzformular zu öffnen. Versuche Token expired-demo, Reset account maya und New password BlockedExpired42!. Erwarte Reset denied. Wechsle anschließend zum Tab Portal Web und wähle Back to portal, um dessen Anmeldeformular wieder zu öffnen. Melde dich als maya mit ResetSafe42! an. Es muss Login accepted erscheinen: Fehlversuche haben das Passwort nicht geändert. Um auch noah zu testen, wähle erneut Back to portal und melde dich mit dessen Demonstrationspasswort CrossDemo42! an; ein reparierter Endpunkt erhält bestehende unbeteiligte Konten.

Wechsle zum Tab App Server. Wiederhole die verwerfbaren Regressionstests:

Wechsle zum Tab App Server, bevor du den folgenden Befehl ausführst.

python3 /opt/reset-lab/check.py handler.py

Alle elf müssen weiter bestehen, einschließlich zweier gleichzeitiger Nutzungen mit genau einer erfolgreichen Rücksetzung. Wiederholungen lassen aktive Kontodaten unverändert. Erlaubte Wiederherstellung und verweigerter Missbrauch gehören zusammen; eine deaktivierte Seite oder ständige Ablehnung ist keine Reparatur.

Die Trainingsanwendung simuliert Zustellung und vereinfacht Identitätsverwaltung. Produktivsysteme brauchen zusätzlich sicheren Mailversand, Ratenbegrenzung, Sitzungsverwaltung und Passwortrichtlinien, die hier außerhalb des Umfangs liegen. Der OWASP-Leitfaden liefert den weiteren Kontext.

Zusammenfassung

Du hast eine echte Rücksetzung ausgeführt, Replay, kontenübergreifende Nutzung und Ablaufprobleme gezeigt und einen kleinen Python-Handler repariert. Gespeicherter Eigentümer, zukünftiger Ablauf, unbenutzter Zustand und atomarer Verbrauch greifen nun zusammen. Verwerfbare HTTP-Tests beweisen gültige Wiederherstellung, verweigerten Missbrauch, unveränderte andere Konten und genau einen Gewinner bei Konkurrenz. Die Personalportal-Challenge überträgt diese Regeln auf eine weitere unvollständige Bedingung.