
Element Web v1.12.29 - Hoch - Remote - Session - Fragment-Gast-Anmeldeinformationen löschen eine echte Sitzung vor whoami
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · element-fragment-guest
Bericht: https://abraxaslabs.tech/research/element-fragment-guest
Element Web v1.12.29 – Element / New Vector
Klasse: Sitzungszerstörung Reichweite: Remote
Lifecycle.loadSession bevorzugt guest_user_id und guest_access_token aus dem URL-Hash gegenüber restoreSessionFromStorage. Gäste sind standardmäßig aktiviert (enableGuest={!config.disable_guests}). Die config.json von app.element.io setzt disable_guests nicht. onTokenLoginCompleted entfernt nur SSO- und OIDC-Parameter. Die Gast-Schlüssel werden nie entfernt. url_utils.ts kommentiert bereits, dass diese Fragment-Parameter ungenutzt erscheinen. Sie gewinnen trotzdem.
Jeder, der einen angemeldeten Benutzer dazu bringt, eine Hash-URL mit Gast-Fragment-Parametern zu öffnen, meldet ihn ab und löscht die lokale Krypto. Ein ungültiges Token genügt. whoami wird nie aufgerufen.
| ID | noch keine CVE |
| CWE | CWE-384 / CWE-352 / CWE-613 |
| CVSS | Hoch: 7.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H |
| Produkt | Element Web |
| Betroffen | v1.12.29 Tag v1.12.29 (2d90d6b7b601ecb9ccdf81239a43b4396b4b0c9e). Gäste aktiviert (Standard). |
| Authentifizierung | nicht authentifizierter Angreifer. Das Opfer muss eine URL öffnen (oder neu laden). |
| Lizenz | GNU Affero GPL v3.0 |
| Labor | nur 127.0.0.1 |
Einen angemeldeten Benutzer dazu bringen, eine Hash-URL mit Gast-Fragment-Parametern zu öffnen. Der Client meldet ihn ab, löscht die lokale Krypto und setzt ihn möglicherweise auf einen Gast des Angreifers. Das ist Abmeldung und Krypto-Löschung. Es ist kein Stehlen des echten Tokens. Es ist kein OS-RCE.
| Berechtigung | Methode / Senke | Recon / Integrität / Verfügbarkeit | Im Labor bewiesen oder abgeleitet |
|---|---|---|---|
| Gast-Anmeldedaten aus dem Hash parsen | url_utils.ts guest: { keys: ["guest_user_id", "guest_access_token"], location: "fragment" } | Integrität der Sitzungsauswahl | Im Labor bewiesen. #/home?guest_user_id=...&guest_access_token=... wurde zu guest_params. Nur Query-String nicht. |
| Gast gegenüber einer gespeicherten Nicht-Gast-Sitzung bevorzugen | Gast-zuerst-Zweig in Lifecycle.loadSession, Log Using guest access credentials | Integrität | Im Labor bewiesen. Das vorbelegte @victim:example.org wurde nicht wiederhergestellt. |
| localStorage, IndexedDB-Konto, sessionStorage, Krypto löschen | doSetLoggedIn(..., clearStorageEnabled=true) dann clearStorage() | Integrität / Verfügbarkeit der lokalen Sitzung | Im Labor bewiesen. crypto_empty=yes, vorheriges Token weg. |
| Token-Validierung überspringen | Der Gast-Pfad ruft nie /_matrix/client/v3/account/whoami auf | Integrität | Im Labor bewiesen. whoami_called=no. Ungültiges Token not-a-real-token löschte trotzdem. |
| Gast-Anmeldedaten des Angreifers persistieren | persistCredentials nach der Löschung | Integrität | Im Labor bewiesen. after_user=@x:example.org, after_token=not-a-real-token, mx_is_guest=true. |
| Auf einen echten Gast auf dem Standard-HS fixieren | Gleiches Persistieren, wenn das Gast-Token gültig ist | Integrität | Abgeleitet. Das Labor verwendete ein ungültiges Token, daher kein Live-HS-Login. |
| Dies bei Neuladen weiter tun | Gast-Schlüssel bleiben im Hash; onTokenLoginCompleted löscht sie nicht | Integrität | Abgeleitet aus dem Pin in app.tsx. Das Labor öffnete die URL einmal. |
Offen blieb dieser Rest: den echten Access-Token stehlen (er wird gelöscht, nicht exfiltriert). OS RCE / LPE (Desktop nodeIntegration: false, Sandbox). Live Element SPA (how=gadget). Query-String ?guest_user_id= (nur Fragment). disable_guests: true behält die Nicht-Gast-Sitzung. Ein gepatchtes loadSession, das Gast ignoriert, wenn eine Nicht-Gast-Sitzung existiert, behält sie ebenfalls.
Weitere Reste aus demselben Pin: vector: Windows-Laufwerksbuchstabe, Univention ICS javascript: href.
Ich habe Element Web v1.12.29 nach dem GitHub-Release vom 22. Sep. 2026 gepinnt. SSO loginToken ist nur per Query-String verfügbar und wird nach der Verwendung entfernt. Gast-Schlüssel liegen weiterhin im Fragment und gewinnen gegenüber der Wiederherstellung. Der Kommentar in url_utils.ts ist der Hinweis: Sie zweifelten bereits an, ob diese Schlüssel spezifiziert waren.
Bereits festgehaltene Irrwege: den Query-String ?guest_user_id= als Vektor zu behandeln (die Schlüssel liegen im Hash); dies als Token-Diebstahl zu bezeichnen (der echte Token wird gelöscht, nicht gesendet); disable_guests in der Konfiguration von app.element.io zu erwarten (es ist nicht gesetzt). Eine Reverse Shell. Theater.
Gadget der Pin-Funktionen. Kein Live-Element-Web-Container. how=gadget.
python3 element-fragment-guest-Abraxas-Labs.py
oder
cd lab
./run.sh
Ziele ausschließlich auf http://127.0.0.1:19600. Compose-Projekt element-fragment-guest. Der Stack wird nach dem Lauf abgebaut.
SUCCESS element-fragment-guest how=gadget guest-wipe=yes prior-kept=no garbage-token=yes disable-guests-keeps=yes ELEMENT-FRAGMENT-GUEST-WITNESS
Ignoriere Gast-Fragmentparameter, wenn bereits eine Nicht-Gast-Sitzung existiert. Validiere das Gast-Token mit /_matrix/client/v3/account/whoami vor clearStorage. Entferne guest_user_id und guest_access_token auf dieselbe Weise, wie SSO-Token entfernt werden. Standardmäßig disable_guests: true für das gehostete app.element.io.
Lifecycle.ts (loadSession Gast zuerst)url_utils.tsapp.tsx (enableGuest={!config.disable_guests})GNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.