
Element Web v1.12.29 — High — Remote — Session — фрагмент guest creds стирает реальную сессию перед whoami
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · element-fragment-guest
Element Web v1.12.29 - Element / New Vector
Класс: Уничтожение сессии Доступ: Удалённый
Lifecycle.loadSession предпочитает guest_user_id и guest_access_token из хэша URL вместо restoreSessionFromStorage. Гостевой режим включён по умолчанию (enableGuest={!config.disable_guests}). В config.json app.element.io не задан disable_guests. onTokenLoginCompleted удаляет только параметры SSO и OIDC. Он никогда не удаляет гостевые ключи. В url_utils.ts уже есть комментарий, что эти параметры фрагмента выглядят неиспользуемыми. Они всё равно побеждают.
Любой, кто может заставить вошедшего пользователя открыть URL с хэшем, содержащим гостевые параметры фрагмента, разлогинивает его и стирает локальные криптоданные. Достаточно мусорного токена. whoami никогда не вызывается.
| ID | CVE пока нет |
| CWE | CWE-384 / CWE-352 / CWE-613 |
| CVSS | Высокий: 7.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H |
| Продукт | Element Web |
| Затронуто | v1.12.29 тег v1.12.29 (2d90d6b7b601ecb9ccdf81239a43b4396b4b0c9e). Гостевой режим включён (по умолчанию). |
| Аутентификация | неаутентифицированный атакующий. Жертва должна открыть (или перезагрузить) URL. |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Заставить вошедшего пользователя открыть URL с хэшем, содержащим гостевые параметры фрагмента. Клиент разлогинивает его, стирает локальные криптоданные и может поместить его в гостевую сессию атакующего. Это разлогинивание и стирание криптоданных. Это не кража настоящего токена. Это не RCE на уровне ОС.
| Привилегия | Метод / точка срабатывания | Разведка / целостность / доступность | Доказано в лаборатории или выведено |
|---|---|---|---|
| Разбор гостевых учётных данных из хэша | url_utils.ts guest: { keys: ["guest_user_id", "guest_access_token"], location: "fragment" } | Целостность выбора сессии | Доказано в лаборатории. #/home?guest_user_id=...&guest_access_token=... стал guest_params. Только строка запроса — нет. |
| Предпочтение гостевой сессии вместо сохранённой негостевой | Ветка Lifecycle.loadSession с приоритетом гостя, лог Using guest access credentials | Целостность | Доказано в лаборатории. Заранее созданная @victim:example.org не была восстановлена. |
| Стирание localStorage, аккаунта IndexedDB, sessionStorage, криптоданных | doSetLoggedIn(..., clearStorageEnabled=true) затем clearStorage() | Целостность / доступность локальной сессии | Доказано в лаборатории. crypto_empty=yes, прежний токен исчез. |
| Пропуск проверки токена | Гостевой путь никогда не вызывает /_matrix/client/v3/account/whoami | Целостность | Доказано в лаборатории. whoami_called=no. Мусорный токен not-a-real-token всё равно привёл к стиранию. |
| Сохранение гостевых учётных данных атакующего | persistCredentials после стирания | Целостность | Доказано в лаборатории. after_user=@x:example.org, after_token=not-a-real-token, mx_is_guest=true. |
| Фиксация на реальном госте на домашнем сервере по умолчанию | То же сохранение, если гостевой токен действителен | Целостность | Выведено. В лаборатории использовался мусорный токен, поэтому живого входа на HS не было. |
| Повторение этого при перезагрузке | Гостевые ключи остаются в хэше; onTokenLoginCompleted их не удаляет | Целостность | Выведено из пина app.tsx. В лаборатории URL открывался один раз. |
Закрыто по этому остатку: кража настоящего access-токена (он удаляется, а не эксфильтруется). RCE / LPE на уровне ОС (Desktop nodeIntegration: false, sandbox). Живой SPA Element (how=gadget). Строка запроса ?guest_user_id= (только фрагмент). disable_guests: true сохраняет негостевую сессию. Исправленный loadSession, который игнорирует гостя при наличии негостевой сессии, также сохраняет её.
Другие остатки того же пина: vector: буква диска Windows, Univention ICS javascript: href.
Я зафиксировал Element Web v1.12.29 после релиза на GitHub 22 сентября 2026 года. SSO loginToken передаётся только в строке запроса и удаляется после использования. Гостевые ключи по-прежнему находятся во фрагменте и побеждают при восстановлении. Комментарий в url_utils.ts — это подсказка: они уже сомневались, что эти ключи были специфицированы.
Уже зафиксированные ошибочные пути: рассмотрение строки запроса ?guest_user_id= как вектора (ключи находятся в хэше); называние этого кражей токена (настоящий токен удаляется, а не отправляется); ожидание disable_guests в конфиге app.element.io (он не задан). Обратная оболочка. Театр.
Гаджет из пина функционирует. Это не живой контейнер Element Web. how=gadget.
python3 element-fragment-guest-Abraxas-Labs.py
или
cd lab
./run.sh
Цель только http://127.0.0.1:19600. Проект Compose element-fragment-guest. Стек удаляется после запуска.
SUCCESS element-fragment-guest how=gadget guest-wipe=yes prior-kept=no garbage-token=yes disable-guests-keeps=yes ELEMENT-FRAGMENT-GUEST-WITNESS
Игнорировать гостевые параметры фрагмента, когда негостевая сессия уже существует. Проверять гостевой токен через /_matrix/client/v3/account/whoami перед clearStorage. Удалять guest_user_id и guest_access_token так же, как удаляются токены SSO. По умолчанию disable_guests: true для размещённого app.element.io.
Lifecycle.ts (loadSession с приоритетом гостя)url_utils.tsapp.tsx (enableGuest={!config.disable_guests})GNU Affero GPL v3.0. См. LICENSE. Только лаборатория на loopback. Без гарантий.