
Element Web v1.12.29 - High - Remote - Session - 게스트 자격 증명이 whoami 실행 전 실제 세션 삭제
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · 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의 실제 게스트로 고정 | 게스트 토큰이 유효하면 동일하게 유지 | 무결성 | 추론. 랩은 쓰레기 토큰을 사용했으므로 실제 HS 로그인은 없음. |
| 새로고침 시에도 계속 실행 | 게스트 키가 해시에 남아 있음; onTokenLoginCompleted가 삭제하지 않음 | 무결성 | 핀 app.tsx에서 추론. 랩은 URL을 한 번 열었음. |
이 잔여물에서 제외된 것: 실제 액세스 토큰 탈취(삭제될 뿐 유출되지 않음). OS RCE / LPE(Desktop nodeIntegration: false, 샌드박스). 라이브 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 참조. 루프백 랩 전용. 보증 없음.