
Element Web v1.12.29 - High - Remote - Session - 게스트 자격 증명이 whoami 실행 전 실제 세션 삭제
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · element-fragment-guest
분석 문서: https://abraxaslabs.tech/research/element-fragment-guest
Element Web v1.12.29 - Element / New Vector
분류: 세션 파괴 도달 범위: 원격
Lifecycle.loadSession은 restoreSessionFromStorage보다 URL 해시의 guest_user_id와 guest_access_token을 우선합니다. 게스트는 기본적으로 활성화되어 있습니다(enableGuest={!config.disable_guests}). app.element.io의 config.json은 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을 열도록 만드세요. 클라이언트는 해당 사용자를 로그아웃시키고 로컬 암호화를 삭제하며, 공격자의 게스트 계정에 배치할 수도 있습니다. 이는 로그아웃 및 암호화 삭제입니다. 실제 토큰을 탈취하는 것이 아닙니다. OS 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의 실제 게스트로 고정 | 게스트 토큰이 유효한 경우 동일한 persist | 무결성 | 추론. 랩은 쓰레기 토큰을 사용했으므로 실제 HS 로그인은 없음. |
| 새로고침 시 계속 이 작업 수행 | 게스트 키가 해시에 남아 있음; onTokenLoginCompleted가 이를 삭제하지 않음 | 무결성 | 고정된 app.tsx에서 추론. 랩은 URL을 한 번 열었음. |
이 남은 부분은 종결되었다: 실제 액세스 토큰을 탈취하라(이것은 삭제되었지, 유출된 것이 아니다). OS RCE / LPE (Desktop nodeIntegration: false, sandbox). 라이브 Element SPA (how=gadget). 쿼리 문자열 ?guest_user_id= (프래그먼트 전용). disable_guests: true는 비게스트 세션을 유지한다. 비게스트 세션이 존재할 때 게스트를 무시하는 패치된 loadSession도 이를 유지한다.
동일한 핀의 잔여물: vector: Windows 드라이브 문자, Univention ICS javascript: href.
2026년 9월 22일 GitHub 릴리스 이후 Element Web v1.12.29를 핀했다. SSO loginToken은 쿼리 전용이며 사용 후 제거된다. 게스트 키는 여전히 프래그먼트에 남아 복원을 이긴다. url_utils.ts의 주석이 단서다: 그들은 이미 이 키들이 명세되지 않았다고 의심했다.
이미 기록된 잘못된 방향: 쿼리 문자열 ?guest_user_id=를 벡터로 취급한 것(키는 해시에 있다); 이것을 토큰 탈취라고 부른 것(실제 토큰은 전송되지 않고 삭제된다); app.element.io 구성에서 disable_guests를 기대한 것(설정되지 않음). 리버스 셸. 연극일 뿐.
핀 함수들의 가젯. 라이브 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
비게스트 세션이 이미 존재하는 경우 게스트 프래그먼트 매개변수를 무시합니다. clearStorage 전에 /_matrix/client/v3/account/whoami로 게스트 토큰을 검증합니다. SSO 토큰이 제거되는 것과 동일한 방식으로 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를 참조하세요. 루프백 실험실 전용입니다. 보증은 제공되지 않습니다.