
Element Web v1.12.29 - 高 - リモート - XSS - Univention ICS navigation.json リンクが javascript: メニュー href になる
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · element-ics-javascript
解説記事: https://abraxaslabs.tech/research/element-ics-javascript
Element Web v1.12.29 - Element / New Vector
クラス: XSS 到達範囲: リモート
Univention バナーモジュールは ICS の navigation.json を取得し、各エントリの link をスキームチェックなしで z.string() として受け入れ、Menu.tsx がその文字列をスタイル付きの <a href> に配置します。静的メニュー設定では link_url に z.url() を使用しています。ICS の経路ではそうなっていません。同じピンにおける URL プレビューはすでに javascript: を拒否しています(previewFromBundle、GHSA-9r5h)。これはデフォルトの app.element.io ではありません。menu.type が univention の modules/banner と、デプロイが信頼する ICS が必要です。
その navigation.json を変更できる者は誰でも javascript: や data: を仕込めます。バナーメニューを開いてその項目をクリックしたサインイン済みユーザーは、Element オリジン上でスクリプトを実行させることになります。
| ID | CVE 未割当 |
| CWE | CWE-79 / CWE-20 |
| CVSS | Medium: 6.8 CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:N |
| 製品 | Element Web |
| 影響範囲 | v1.12.29 タグ v1.12.29(2d90d6b7b601ecb9ccdf81239a43b4396b4b0c9e)。条件付き: Univention バナー + ICS。 |
| 認証 | ICS 運用者 / ICS の侵害。被害者はメニュー項目をクリックするサインイン済みユーザー。 |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
Element のデプロイが信頼する ICS を侵害するか運用します。navigation.json に javascript:(または data:)URL を入れます。サインイン済みユーザーがバナーメニューを開いてその項目をクリックするのを待ちます。これは Matrix アカウントの乗っ取りです。アクセストークン、暗号ストア、セッションが対象です。OS の RCE ではありません。デスクトップでは依然として nodeIntegration はオフで、サンドボックスがあります。
| 権限 | 手法 / シンク | 偵察 / 完全性 / 可用性 | ラボ実証または推測 |
|---|---|---|---|
Element オリジン上でバナーメニューの <a href="javascript:…"> をレンダリングする | ICS navigation.json の entries[].link -> navigationToConfig の link_url -> Menu.tsx の LinkButton href={link.link_url} | メニュー DOM の完全性 | ラボ実証済み。モック ICS のリンク javascript:ELEMENT-ICS-JAVASCRIPT-WITNESS がその href になりました。https のポータルリンクは引き続きレンダリングされました |
| クリック後に Element オリジンとしてスクリプトを実行する | 被害者がメニュー項目をクリックする(UI:R) | 完全性 | href シンクからの推測。ラボではブラウザのクリックを実行したり、実際の Matrix トークンを窃取したりしていません |
| Matrix アクセストークン / 暗号ストアを読み取る(アカウント乗っ取り) | オリジン内スクリプト対 localStorage / IndexedDB セッション | 偵察 / 完全性 | Element オリジン XSS からの推測。ラボの証拠は href 文字列です |
| Element タブをフィッシングページへトップナビゲートする | SilentLogin.tsx のサンドボックスなし iframe src={new URL("silent", icsUrl)} | 完全性 | iframe に sandbox がないことをラボで実証済み。トップナビゲーションは未検証 |
data: による同様の仕込み | z.string() は任意のスキームを受け入れる | 完全性 | 推測。ラボでは javascript: のみを仕込みました |
このピンではクローズ済み: デフォルトの app.element.io(Univention バナーなし)。OS RCE / LPE(デスクトップの nodeIntegration: false、サンドボックス、contextIsolation)。タイムライン HTML XSS。URL プレビューの javascript:(GHSA-9r5h の previewFromBundle は http:/https: を要求)。HTML エクスポート XSS(GHSA-wqmv)。ウィジェットのメディアトークン(GHSA-3jm3)。静的バナーの link_url: z.url() はオペレーター設定であり ICS ではない。また z.url() は http/https の許可リストでもない。
同じピンの残件: フラグメントのゲストワイプ、vector: の Windows ドライブレター。
2026年9月22日の GitHub リリース後、Element Web v1.12.29 をピン留めした。URL プレビューは既に苦労して http:/https: を学習済みだった。Univention ICS の link は依然として z.string() のまま。静的メニュー設定は z.url() を使用している。取得経路はそのチェックを一切通らない。
既に記録済みの誤った道筋: デフォルトの app.element.io を被害者とみなすこと(Univention はゲートされている);z.url() をスキーム許可リストとみなすこと(URL コンストラクタは javascript: を受け入れる);クリック XSS を OS RCE に誇張すること。リバースシェル。茶番である。
ピンの関数群に加え、モックの ICS navigation.json を用いたガジェット。実際の Element Web コンテナではない。how=gadget。URL プレビューの http/https 許可リスト(previewFromBundle)を適用すると、javascript の href は除外され、https のポータルリンクは維持された。
python3 element-ics-javascript-Abraxas-Labs.py
または
cd lab
./run.sh
対象は http://127.0.0.1:19620 のみです。プロジェクト element-ics-javascript を構成します。実行後、スタックは破棄されます。
SUCCESS element-ics-javascript how=gadget href-scheme=javascript menu-a-javascript=yes allowlist-rejects=yes silent-no-sandbox=yes ELEMENT-ICS-JAVASCRIPT-WITNESS
ICS の link に対して、previewFromBundle と同じ方法で http: と https: を許可リストに追加する。href= の前に javascript:、data:、その他のスキームを拒否する。サイレント iframe をサンドボックス化する(sandbox=""、または少なくとも allow-top-navigation を付けない)。z.url() をスキームの許可リストとして扱わないこと。
navigation.tsMenu.tsxSilentLogin.tsxpreviewFromBundleGNU Affero GPL v3.0。LICENSE を参照。ループバックラボ専用。保証なし。