
Prueba de concepto de explotación para la omisión de autorización de BrowsingContext en Firefox (CVE-2026-4692), que demuestra mensajes IPC falsificados para establecer InRDMPane y habilitar la inyección privilegiada de eventos táctiles en la interfaz de usuario.
Prueba de concepto de una verificación de autorización faltante en la sincronización
del campo BrowsingContext: un proceso de contenido comprometido falsifica un
mensaje PContent::CommitBrowsingContextTransaction estableciendo InRDMPane = true
en su propio BrowsingContext de nivel superior, y el proceso padre lo aplica.
Objetivo: Firefox 149.0a1 nightly @ 2fbc0748c4 (vulnerable, pre-arreglo), macOS arm64.
Corregido en Firefox 149 — bug 2017643, commit a9279ce332ed ("Prevent toggling RDM
BrowsingContext flag from content processes"), que añade:
bool BrowsingContext::CanSet(FieldIndex<IDX_InRDMPane>, const bool&,
ContentParent* aSource) {
return XRE_IsParentProcess() && IsTop() && !aSource; // rechazar si viene de content
}
InRDMPane le indica al proceso padre que la pestaña es un panel de Responsive Design Mode. El
proceso padre confía en esto al realizar hit-testing de eventos táctiles sintetizados
(BrowserParent::RecvDispatchTouchEvent): se permite que los eventos dirigidos nominalmente a un panel
de RDM aterricen en UI chrome privilegiada. Un proceso de contenido comprometido
que establece el indicador puede entonces enviar eventos táctiles con coordenadas negativas/fuera del contenido
y hacer clic en UI privilegiada sin interacción del usuario (ver el repro.patch del
informante en el bug 2017643, que demuestra exactamente eso con una compilación parcheada). Este repositorio
demuestra la violación del límite habilitante en sí misma, con una falsificación de mensaje real — sin
parches de código fuente del navegador.
PContent::CommitBrowsingContextTransaction — tipo de mensaje 0x3a0137
(PContentMsgStart=58 << 16 | ordinal 311), enrutamiento MSG_ROUTING_CONTROL
(INT64_MAX), indicadores NOT_NESTED (0x001):
u64 bcid centinela 235406151 ('aContext')
u64 0x0000000000800000 bitset modificado palabra0 (bit 23 = InRDMPane)
u64 0 bitset palabra1 (¡las palabras de BitSet<84> son size_t = u64!)
u32 1 WriteBool(true)
u32 523371752 centinela 'aTransaction'
u64 epoch (la verificación de epoch es solo MOZ_ASSERT; compilada fuera aquí)
u32 132121169 centinela 'aEpoch'
La entrega reutiliza la ruta de envío de CVE-2026-74939: operator new →
IPC::Message::Message(routing, type, capacity, flags) → Pickle::WriteBytes →
MessageChannel::Send en el canal PContent, controlado desde JS mediante la primitiva
de llamada funcref de wasm (wasm-bytes.js, etapa-1 = CVE-2026-2796).
Registro del lado del proceso padre (MOZ_LOG=BrowsingContextSync:5) después de ./irun:
D/BrowsingContextSync Transaction::Apply(#380000001, ipc): InRDMPane(false->true)
#380000001 es el BrowsingContext de nivel superior de la ventana emergente (id asignado por el
hijo, creado from IPC), e ipc marca la transacción como originada por contenido.
En una compilación corregida, el mismo mensaje falla la validación de CanSet y es rechazado.
Requisitos previos: compilación Nightly vulnerable en /Users/sid/gecko-2766/obj-browser,
.venv con psutil, y el servidor de registro incluido ejecutándose:
python3 srv.py > /tmp/srv4692.log 2>&1 & # sirve este directorio en :8781
python3 forge_bctx.py # construye bctx.bin/bctx.json
./irun # lanzar + inyectar + recopilar evidencia
a9279ce332ed (MFSA 2026-20, Firefox 149)../poc-cve-2026-74939)../poc-cve-2026-12295)| Archivo | Propósito |
|---|
bctx.html | Página PoC: calcula el id del BC de la ventana emergente en tiempo de ejecución, lo parchea en el mensaje falsificado, lo envía |
forge_bctx.py | construye bctx.bin/bctx.json (autoverificable), completamente estático excepto el id del BC |
wasm-bytes.js | primitivas de etapa-1: R/W arbitrario, llamadas funcref |
mdrive2.py | arnés de marionette |
irun | ejecución instrumentada: lldb attach + evidencia de BrowsingContextSync |
srv.py | servidor web de registro para las páginas PoC (:8781) |
profile.user.js | preferencias del perfil de Firefox (fission activado, dump habilitado) |