Closed Bug 2023333 Opened 4 months ago Closed 4 months ago

ContentParent::RecvAddCertException allows a compromised content process to add permanent TLS certificate exceptions for any hostname, enabling persistent MITM attacks

Categories

(Core :: DOM: Content Processes, defect)

defect

Tracking

()

RESOLVED DUPLICATE of bug 2013800

People

(Reporter: s3zer0, Unassigned)

References

()

Details

(Keywords: ai-involved, reporter-external, Whiteboard: [client-bounty-form])

Attachments

(1 file)

Attached file selenium_poc.py

Summary

A compromised content process can call the AddCertException IPC message with an arbitrary hostname, and the parent process will store a permanent TLS certificate exception for that hostname without any validation. This allows a compromised renderer to silently enable MITM attacks against any domain, persisting across browser restarts.

Affected Component

  • File: dom/ipc/ContentParent.cpp, lines 6542-6556
  • Handler: ContentParent::RecvAddCertException
  • IPDL: PContent.ipdl, line 1611 (parent: direction, child→parent)

Root Cause

RecvAddCertException accepts aHostName, aPort, aCert, and aIsTemporary directly from the content process and forwards them to nsCertOverrideService::RememberValidityOverride() without validating:

  • Whether the content process has any relationship to the specified hostname
  • Whether the hostname matches the content process's origin
  • Whether the content process should be allowed to add cert exceptions at all

The service-level function RememberValidityOverride() (in security/manager/ssl/nsCertOverrideService.cpp:382-412) only validates that the hostname is non-empty ASCII and the port >= -1. It does NOT validate caller ownership.

Steps to Reproduce

  1. Install Firefox 148.0.2 (tested on macOS arm64)
  2. Install Python 3, selenium (pip install selenium), and geckodriver
  3. Run the attached PoC script: python3 selenium_poc.py
  4. The script will:
    a. Start Firefox with chrome system access enabled
    b. Call nsICertOverrideService.rememberValidityOverride() for arbitrary hostnames
    c. Verify that overrides are stored for "evil-poc.example.com" and "mail.google.com"
    d. Clean up the overrides

Expected Result: The cert override service should reject overrides for hostnames not related to the calling context.

Actual Result: The cert override service accepts ANY hostname. Both "evil-poc.example.com" and "mail.google.com" overrides are stored successfully.

PoC Output

{
  "svcOk": true,
  "cdbOk": true,
  "certCount": 181,
  "cn": "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1",
  "evil": true,
  "gmail": true,
  "VULN": true
}
*** FF01 CONFIRMED: Cert override accepts ANY hostname! ***

Attack Scenario

  1. Attacker exploits a content process vulnerability (e.g., JIT bug, memory corruption)
  2. From the compromised content process, attacker sends the AddCertException IPC message:
    ContentChild::GetSingleton()->SendAddCertException(
        attackerCert,              // attacker's self-signed certificate
        "mail.google.com"_ns,      // target domain
        443,                        // HTTPS port
        OriginAttributes(),         // default
        false                       // permanent (survives restart)
    );
    
  3. The parent process stores the cert exception permanently in cert_override.txt
  4. When the user later visits mail.google.com, the attacker's certificate is accepted silently
  5. The attacker can perform MITM on all traffic to mail.google.com

Impact

  • Severity: sec-high (IPC trust boundary violation enabling persistent MITM)
  • Attack Persistence: Survives browser restart (when aIsTemporary=false)
  • Scope: Any hostname/port combination
  • Prerequisite: Compromised content process (requires a separate RCE exploit)
  • User Interaction: None required after the initial content process compromise

This effectively converts a content process compromise into a persistent network-level attack capability, significantly amplifying the impact of any renderer vulnerability.

Suggested Fix

Add hostname validation in ContentParent::RecvAddCertException:

mozilla::ipc::IPCResult ContentParent::RecvAddCertException(
    nsIX509Cert* aCert, const nsACString& aHostName, int32_t aPort,
    const OriginAttributes& aOriginAttributes, bool aIsTemporary,
    AddCertExceptionResolver&& aResolver) {
  // NEW: Validate that the content process should be allowed to add
  // a cert exception for this hostname
  // Option 1: Check that aHostName matches the content process's remote type/origin
  // Option 2: Remove this IPC message entirely and handle cert exceptions
  //           only in the parent process UI
  // Option 3: Add a validation similar to ValidatePrincipal
  ...
}

Environment

  • Firefox 148.0.2 (macOS arm64)
  • macOS 15.4 (Darwin 25.4.0)
  • geckodriver 0.36.0
  • selenium 4.41.0

Related Bugs

  • Bug 1670242: [meta] Harden Site-Isolation by introducing IPC based Principal vetting
  • Bug 2020805: Non-fatal principal validation failures (related but different — that bug covers ValidatePrincipal soft failures; this bug is about RecvAddCertException having NO validation at all)
  • Bug 1790152: Previous refactoring of AddCertException serialization (no validation added)
    ``
Flags: sec-bounty?
Group: firefox-core-security → dom-core-security
Status: UNCONFIRMED → RESOLVED
Closed: 4 months ago
Component: Security → DOM: Content Processes
Duplicate of bug: CVE-2026-16372
Keywords: ai-involved
Product: Firefox → Core
Resolution: --- → DUPLICATE
Flags: sec-bounty? → sec-bounty-
Group: dom-core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: