Compromised content process can plant a certificate override for arbitrary host/port pairs
Categories
(Core :: DOM: Content Processes, defect)
Tracking
()
People
(Reporter: chris, Unassigned)
Details
(Keywords: reporter-external, Whiteboard: [client-bounty-form])
Attachments
(4 files)
Base revision
Patch applies cleanly to mozilla-firefox/firefox (mozilla-central) at rev ad5f057320ecc6b934dfa1e3ec361f87712806cc (2026-04-20). Verified with git apply --check against a pristine HEAD subtree.
Description
A compromised content process can cause Firefox to store a certificate exception for an arbitrary host, even though the user only approved a certificate warning for a different host controlled by that renderer.
In the proof below, approving the warning at attacker.test:8443 causes Firefox to store an override for victim.test:8443. After that, victim.test:8443 loads without its own certificate warning. The generated profile's cert_override.txt contains a victim.test:8443 entry, showing the override was persisted on disk.
This is not itself a live MITM. The security consequence is that a post-renderer-compromise attacker can pre-authorize an attacker-chosen certificate for an arbitrary host/port pair, enabling later certificate-warning bypass / silent TLS interception for that target when the attacker can present that certificate.
Cause
The IPC handler
mozilla::dom::ContentParent::RecvAddCertException(aCert, aHostName, aPort, aOriginAttributes, aIsTemporary)
(dom/ipc/ContentParent.cpp:6534) forwards (aHostName, aPort, aOriginAttributes, aCert, aIsTemporary) directly to nsCertOverrideService::RememberValidityOverride. Neither the handler nor the override service checks that the calling content process is actually handling a failed channel for aHostName:aPort.
The legitimate child-side caller is Document::AddCertException (dom/base/Document.cpp:1594). That code derives host, port, and cert from mFailedChannel and its nsITransportSecurityInfo. A compromised renderer can keep the real cert object and real cert-error flow, but replace only host / port immediately before SendAddCertException(...). The parent trusts those substituted fields and stores the override for the wrong origin.
Threat model
Same as bug 1899154: attacker has memory-corruption RCE in a content process and patches the outgoing IPC at the marshalling layer. The PoC patch simulates this one frame above marshalling, at the last child-side call site before IPC.
Steps to reproduce (Firefox for Linux)
Tested against mozilla-firefox/firefox revision ad5f057320ec (2026-04-20 mozilla-central tip).
- Add hostnames:
echo "127.0.0.1 attacker.test victim.test" | sudo tee -a /etc/hosts - Apply the attached
0001-attacker-add-cert-exception.patchand build
(any non-debugmach build). - Generate a self-signed test cert for both names using the attached
openssl-san.cnf:openssl req -x509 -nodes -newkey rsa:2048 -days 365 \ -keyout key.pem \ -out cert.pem \ -config openssl-san.cnf \ -extensions v3_req - Run the attached HTTPS fixture:
python3 serve_https.py - Start Firefox on a clean profile, telling the PoC to forge the victim target:
MOZ_IPC_TRUST_PoC_ADDCERT=victim.test:8443 \ ./mach run --temp-profile - On the fresh profile, first visit
https://victim.test:8443/and
confirm Firefox shows a certificate warning. - Then visit
https://attacker.test:8443/and click through its
certificate warning once. - Visit
https://victim.test:8443/again. It now loads without its own
warning, even though no exception was ever approved forvictim.test. - Inspect the temporary profile's
cert_override.txt. It contains:victim.test:8443: ...
Observed result: victim.test:8443 warned on a clean profile before step 7, then loaded successfully after approving only attacker.test:8443. The profile's cert_override.txt contained a persisted victim.test:8443 override entry.
The patch is dormant when the env var is unset.
Affected versions
Reproduced on mozilla-firefox/firefox rev ad5f057320ec (2026-04-20).
Attachments
0001-attacker-add-cert-exception.patch- single-file patch againstdom/base/Document.cppserve_https.py- minimal HTTPS fixture that serves bothattacker.testandvictim.testopenssl-san.cnf- OpenSSL config used to generate the repro certmozconfig- local build config used to reproduce
| Reporter | ||
Comment 1•3 months ago
|
||
| Reporter | ||
Comment 2•3 months ago
|
||
| Reporter | ||
Comment 3•3 months ago
|
||
Updated•3 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Description
•