Closed Bug 2025063 Opened 4 months ago Closed 4 months ago

Sandbox escape: RecvAddCertException allows any content process to add persistent TLS certificate overrides for arbitrary hostnames (MITM enablement)

Categories

(Core :: DOM: Content Processes, defect)

defect

Tracking

()

RESOLVED DUPLICATE of bug 2013800

People

(Reporter: hanaputrarayhan, Unassigned)

Details

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

Attachments

(1 file)

Discovery

  • Method: Manual source code audit of IPC message handlers in dom/ipc/ContentParent.cpp
  • Firefox version: mozilla-central trunk, affects all current versions
  • OS: All platforms

Root Cause

The IPC handler ContentParent::RecvAddCertException at dom/ipc/ContentParent.cpp:6540-6554 allows any content (renderer) process to add TLS certificate overrides for arbitrary hostnames with zero authorization:

mozilla::ipc::IPCResult ContentParent::RecvAddCertException(
    nsIX509Cert* aCert, const nsACString& aHostName, int32_t aPort,
    const OriginAttributes& aOriginAttributes, bool aIsTemporary,
    AddCertExceptionResolver&& aResolver) {
  nsCOMPtr<nsICertOverrideService> overrideService =
      do_GetService(NS_CERTOVERRIDE_CONTRACTID);
  if (!overrideService) {
    aResolver(NS_ERROR_FAILURE);
    return IPC_OK();
  }
  // NO AUTHORIZATION CHECK - directly stores the override
  nsresult rv = overrideService->RememberValidityOverride(
      aHostName, aPort, aOriginAttributes, aCert, aIsTemporary);
  aResolver(rv);
  return IPC_OK();
}

Missing Checks

  1. No process type check. Any content process can send AddCertException. The message is defined under parent: in dom/ipc/PContent.ipdl (line 1609) with no annotations restricting sender type. It should be restricted to PRIVILEGEDABOUT_REMOTE_TYPE (about:certerror).

  2. No hostname validation. The handler accepts any hostname. A compromised renderer for evil.com can add cert overrides for bankofamerica.com.

  3. WebIDL gate is irrelevant. Document.webidl gates the JS API with [Func="Document::CallerIsTrustedAboutCertError"], but this check runs in the content process. A compromised renderer calls ContentChild::SendAddCertException() directly on the PContent IPC channel, bypassing the WebIDL gate entirely.

  4. No authorization in the service. RememberValidityOverride at security/manager/ssl/nsCertOverrideService.cpp:380-410 only validates hostname is non-empty and ASCII, then unconditionally stores.

  5. Overrides persist to disk. When aIsTemporary=false, the override is written to cert_override.txt and persists across browser restarts.

IPC Flow

CONTENT PROCESS (compromised)          PARENT PROCESS

ContentChild::SendAddCertException(    ContentParent::RecvAddCertException(
  attackerCert,            ------>       aCert,
  "bankofamerica.com",     ------>       aHostName,       <-- ANY hostname
  443,                     ------>       aPort,
  OriginAttributes(),      ------>       aOriginAttributes,
  false                    ------>       aIsTemporary)    <-- false = PERMANENT
)
                                         |
                                         | NO CHECK: mRemoteType?
                                         | NO CHECK: hostname matches browsing?
                                         | NO CHECK: user action?
                                         v
                                       RememberValidityOverride("bankofamerica.com", ...)
                                         |
                                         v
                                       cert_override.txt (PERSISTS TO DISK)
                                       ALL future HTTPS to bankofamerica.com
                                       accept attacker's certificate (MITM)

Impact

A compromised content process can:

  • Add permanent TLS certificate overrides for any hostname (banking, email, etc.)
  • Supply an attacker-controlled certificate
  • Overrides affect all future connections from any process, not just the compromised one
  • Enables silent, persistent MITM attacks on any HTTPS website

Per Mozilla's bounty program: "Vulnerabilities that assume arbitrary code execution in the content process - such as invoking an IPC method with attacker-controlled parameters - do qualify for Highest Impact."

Comparison With Other Handlers

Other security-sensitive IPC handlers in ContentParent.cpp check mRemoteType to restrict to privileged process types. For example, RecvGetSystemIcon (line 3457) verifies privileged process type. RecvAddCertException is inconsistent in lacking this check.

Exploitation Steps (conceptual)

  1. Achieve code execution in any content process (via a separate vulnerability)
  2. From the compromised process, call:
ContentChild::GetSingleton()->SendAddCertException(
    attackerCert, "target-bank.com"_ns, 443,
    OriginAttributes(), false /* permanent */);
  1. Parent process stores the override without any checks
  2. User later visits target-bank.com -> Firefox accepts the attacker's certificate

Suggested Fix

mozilla::ipc::IPCResult ContentParent::RecvAddCertException(...) {
  if (mRemoteType != PRIVILEGEDABOUT_REMOTE_TYPE) {
    return IPC_FAIL(this, "AddCertException from non-privileged process");
  }
  // ... existing code
}

Also consider validating that aHostName matches a cert error actually shown by the content process.

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
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: