abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · element-fragment-guest
Element Web v1.12.29 - Element / New Vector
类别: 会话销毁 可达性: 远程
Lifecycle.loadSession 优先使用 URL hash 中的 guest_user_id 和 guest_access_token,而非 restoreSessionFromStorage。访客模式默认开启(enableGuest={!config.disable_guests})。app.element.io 的 config.json 未设置 disable_guests。onTokenLoginCompleted 仅剥离 SSO 和 OIDC 参数,从不剥离访客密钥。url_utils.ts 中已有注释指出这些 fragment 参数看似未被使用。但它们仍然生效。
任何能让已登录用户打开带有访客 fragment 参数的 hash URL 的人,都能使其登出并清除本地加密数据。一个无效 token 就足够了。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 |
让已登录用户打开带有访客 fragment 参数的 hash URL。客户端会使其登出、清除本地加密数据,并可能将其置于攻击者的访客会话中。这是登出和加密数据清除,不是窃取真实 token,也不是操作系统 RCE。
| 权限 | 方法 / 汇聚点 | 侦察 / 完整性 / 可用性 | 实验验证或推断 |
|---|---|---|---|
| 从 hash 解析访客凭据 | 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,之前的 token 已消失。 |
| 跳过 token 验证 | 访客路径从不调用 /_matrix/client/v3/account/whoami | 完整性 | 实验验证。whoami_called=no。无效 token not-a-real-token 仍然触发了清除。 |
| 持久化攻击者的访客凭据 | 清除后执行 persistCredentials | 完整性 | 实验验证。after_user=@x:example.org,after_token=not-a-real-token,mx_is_guest=true。 |
| 在默认 HS 上固定到真实访客 | 若访客 token 有效,则同样的持久化 | 完整性 | 推断。实验使用了无效 token,因此没有实时 HS 登录。 |
| 重新加载后继续生效 | 访客密钥保留在 hash 中;onTokenLoginCompleted 不会删除它们 | 完整性 | 从 pin app.tsx 推断。实验仅打开 URL 一次。 |
以下遗留问题已排除:窃取真实访问 token(它被删除,而非被外泄)。操作系统 RCE / LPE(Desktop nodeIntegration: false,沙箱)。实时 Element SPA(how=gadget)。查询字符串 ?guest_user_id=(仅限 fragment)。disable_guests: true 会保留非访客会话。修补后的 loadSession 在存在非访客会话时忽略访客,也会保留会话。
同一 pin 的遗留问题:vector: Windows 盘符、Univention ICS javascript: href。
在 2026 年 9 月 22 日 GitHub 发布后,我固定了 Element Web v1.12.29。SSO loginToken 仅存在于查询字符串中,并在使用后被剥离。访客密钥仍留在 fragment 中,并优先于恢复。url_utils.ts 中的注释就是线索:他们本就怀疑这些密钥未被规范定义。
已记录的弯路:将查询字符串 ?guest_user_id= 视为攻击向量(密钥实际位于 hash 中);称此为 token 窃取(真实 token 被删除,而非被发送);期望 app.element.io 配置中有 disable_guests(实际未设置)。一个反向 shell。纯属表演。
pin 功能的 gadget。不是实时 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
当已存在非访客会话时,忽略访客 fragment 参数。在 clearStorage 之前,通过 /_matrix/client/v3/account/whoami 验证访客 token。像剥离 SSO token 一样剥离 guest_user_id 和 guest_access_token。对托管的 app.element.io 默认设置 disable_guests: true。
Lifecycle.ts(loadSession 访客优先)url_utils.tsapp.tsx(enableGuest={!config.disable_guests})GNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。无担保。