Die Grenze des Rücksetzlinks reparieren

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.

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.

Suche in Portal Web nach Request a reset link. Trage maya bei Recovery account ein und klicke auf Send reset link. Es erscheint Link requested. Open Local Mailbox. Aktualisiere Mailbox Web: Die neueste Nachricht steht oben und enthält Empfänger, Open reset link und den Tokenwert.

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.

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.

Öffne Portal Web, aktualisiere bei Bedarf und 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.

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.

Fordere in Portal Web einen neuen Link für maya an. Aktualisiere Mailbox Web, öffne die neueste Nachricht und setze das Passwort auf DemoPass42!. Öffne den Link aus derselben Nachricht erneut und setze ReplayDemo42!. Beide Anfragen zeigen Reset accepted. Die zweite müsste abgelehnt werden: Das ist ein Replay, die erneute Nutzung einer bereits verbrauchten Berechtigung.

Öffne denselben Link nochmals. Ändere Reset account zu noah und New password zu CrossDemo42!; klicke auf Reset password. Die Anfrage wird angenommen. Melde dich in Portal Web als noah mit CrossDemo42! an. Ein für maya ausgestellter Link hat noah geändert: Die Bindung zwischen Token und Konto fehlt.

Trage schließlich im Rücksetzformular von Portal Web Token expired-demo, Reset account maya und New password ExpiredDemo42! ein. Klicke auf Reset password. Dieses vorbereitete Token lief bereits eine Stunde vor dem Einrichten ab. Trotzdem wird es angenommen: Der Server ignoriert die Uhr. Du musst keinen Timer abwarten.

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.

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

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.

Fordere in Portal Web einen frischen Link für maya an. Aktualisiere Mailbox Web, öffne die neueste Nachricht und setze ResetSafe42!. Erwarte Reset accepted und HTTP 200. Öffne den Link aus derselben Nachricht nochmals und versuche ReplayAgain42! für maya. Erwarte Reset denied und HTTP 403.

Fordere einen weiteren neuen maya-Link an. Öffne ihn, ändere Reset account zu noah und versuche BlockedCross42!. Erwarte eine Ablehnung. Diese darf den unbenutzten Link des Eigentümers nicht verbrauchen: Öffne dieselbe Nachricht erneut, lasse maya stehen und setze ResetSafe42!. Das muss gelingen.

Versuche im Formular Token expired-demo, Reset account maya und New password BlockedExpired42!: erwartet wird Ablehnung. Melde dich anschließend in Portal Web als maya mit ResetSafe42! an. Login accepted zeigt, dass Fehlversuche das Passwort nicht geändert haben. Auch noah kann sich mit dem Demonstrationspasswort CrossDemo42! anmelden; andere Konten bleiben erhalten.

Wiederhole in App Server die verwerfbaren Regressionstests:

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.