## https://sploitus.com/exploit?id=3653244A-B95E-5EEC-9525-E0BB1AED89B4
# CVE-2026-4692 β content processes can declare themselves in RDM
Proof of concept for a missing authorization check on BrowsingContext field
synchronization: a compromised content process forges a
`PContent::CommitBrowsingContextTransaction` message setting `InRDMPane = true`
on its own top-level BrowsingContext, and the parent **applies it**.
Target: Firefox 149.0a1 nightly @ `2fbc0748c4` (vulnerable, pre-fix), macOS arm64.
Fixed in Firefox 149 β bug 2017643, commit `a9279ce332ed` ("Prevent toggling RDM
BrowsingContext flag from content processes"), which adds:
```cpp
bool BrowsingContext::CanSet(FieldIndex, const bool&,
ContentParent* aSource) {
return XRE_IsParentProcess() && IsTop() && !aSource; // reject if from content
}
```
## Why it matters
`InRDMPane` tells the parent that the tab is a Responsive Design Mode pane. The
parent trusts this when hit-testing synthesized touch events
(`BrowserParent::RecvDispatchTouchEvent`): events nominally targeting an RDM pane
are allowed to land on **privileged chrome UI**. A compromised content process
that sets the flag can then send touch events with negative/off-content
coordinates and click privileged UI without user interaction (see the reporter's
`repro.patch` on bug 2017643, which demonstrates exactly that with a patched
build). This repo demonstrates the enabling boundary violation itself, with a
real message forge β no browser source patches.
## The message (wire format, extracted from the build's generated IPC code)
`PContent::CommitBrowsingContextTransaction` β message type `0x3a0137`
(`PContentMsgStart=58 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'
```
Delivery reuses the CVE-2026-74939 send path: `operator new` β
`IPC::Message::Message(routing, type, capacity, flags)` β `Pickle::WriteBytes` β
`MessageChannel::Send` on the PContent channel, driven from JS via the wasm
funcref-call primitive (`wasm-bytes.js`, stage-1 = CVE-2026-2796).
## Evidence
Parent-side log (`MOZ_LOG=BrowsingContextSync:5`) after `./irun`:
```
D/BrowsingContextSync Transaction::Apply(#380000001, ipc): InRDMPane(false->true)
```
`#380000001` is the popup's top-level BrowsingContext (child-allocated id,
created `from IPC`), and `ipc` marks the transaction as content-originated.
On a fixed build the same message fails `CanSet` validation and is rejected.
## Files
| File | Purpose |
| ---- | ------- |
| `bctx.html` | PoC page: computes the popup BC id at runtime, patches it into the forged message, sends it |
| `forge_bctx.py` | builds `bctx.bin`/`bctx.json` (self-verifying), fully static except the BC id |
| `wasm-bytes.js` | stage-1 primitives: arb R/W, funcref calls |
| `mdrive2.py` | marionette harness |
| `irun` | instrumented run: lldb attach + BrowsingContextSync evidence |
| `srv.py` | logging web server for the PoC pages (:8781) |
| `profile.user.js` | Firefox profile prefs (fission on, dump enabled) |
## Run
Prerequisites: vulnerable Nightly build at `/Users/sid/gecko-2766/obj-browser`,
`.venv` with psutil, and the bundled logging server running:
```
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
```
## References
- Mozilla bug 2017643 β fix commit `a9279ce332ed` (MFSA 2026-20, Firefox 149)
- CVE-2026-74939 β the send-path machinery this reuses (`../poc-cve-2026-74939`)
- CVE-2026-12295 β sibling load-state forge (`../poc-cve-2026-12295`)