Closed Bug 2027566 Opened 3 months ago Closed 3 months ago

RecvAddCertException: no validation of child-supplied hostname

Categories

(Core :: DOM: Content Processes, defect)

defect

Tracking

()

RESOLVED DUPLICATE of bug 2013800

People

(Reporter: kq5y, Unassigned)

Details

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

ContentParent::RecvAddCertException (dom/ipc/ContentParent.cpp, line 6507) passes child-controlled aHostName, aPort, aCert, aOriginAttributes and aIsTemporary directly to nsICertOverrideService::RememberValidityOverride() without any validation.

https://searchfox.org/mozilla-central/source/dom/ipc/ContentParent.cpp#6507

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();
  }
  nsresult rv = overrideService->RememberValidityOverride(
      aHostName, aPort, aOriginAttributes, aCert, aIsTemporary);
  aResolver(rv);
  return IPC_OK();
}

The handler has no principal check and no verification that aHostName matches the content process's actual failed channel. A compromised content process can send AddCertException with an arbitrary hostname and aIsTemporary=false, causing a permanent certificate override entry to be written to cert_override.txt.

Compare with the immediately adjacent handler (line 6524), which validates its principal:

mozilla::ipc::IPCResult
ContentParent::RecvAutomaticStorageAccessPermissionCanBeGranted(
    nsIPrincipal* aPrincipal, ...) {
  if (!aPrincipal) {
    return IPC_FAIL(this, "No principal");
  }
  if (!ValidatePrincipal(aPrincipal)) {
    LogAndAssertFailedPrincipalValidationInfo(aPrincipal, __func__);
  }
  ...
}

RecvAddCertException does not even have a principal parameter.

The normal caller is Document::AddCertException() (dom/base/Document.cpp, line 1592), gated by CallerIsTrustedAboutCertError, which derives hostname and cert from the actual failed channel. A compromised content process bypasses that path and calls SendAddCertException directly with attacker-chosen values.

The override is effective for hosts where OverrideAllowedForHost() (SSLServerCertVerification.cpp, line 309) permits overrides. HSTS-preloaded and pinned hosts are not affected.

Verified on Firefox Nightly 151.0a1 (Build ID 20260327092354, macOS). I confirmed the child-to-parent IPC path persists overrides to cert_override.txt by navigating to https://self-signed.badssl.com/, accepting the exception via document.addCertException(false), and checking the profile directory. The arbitrary-host claim is based on source inspection of the handler, which places no constraint on aHostName.

Flags: sec-bounty?
Group: firefox-core-security → dom-core-security
Status: UNCONFIRMED → RESOLVED
Closed: 3 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.