RecvAddCertException allows content process to install permanent cert overrides for arbitrary hostnames
Categories
(Core :: Security: PSM, defect)
Tracking
()
People
(Reporter: jmwebdevelopement, Unassigned)
Details
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
Steps to reproduce:
ContentParent::RecvAddCertException in dom/ipc/ContentParent.cpp (around line 6520) takes an nsIX509Cert, hostname string, port, origin attributes, and isTemporary bool from the content process. It passes all 5 parameters directly to nsICertOverrideService::RememberValidityOverride with no validation:
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();
}
No ValidatePrincipal, no origin check, no mechanism to verify the request originated from a cert error page UI flow, no process-type restriction. AddCertException is defined in PContent.ipdl as a parent: message so any content child can send it.
RememberValidityOverride (security/manager/ssl/nsCertOverrideService.cpp around line 380) only validates hostname format (non-empty, ASCII) and that the cert is non-null. it writes directly to cert_override.txt via AddEntryToList + Write. when isTemporary is false the override persists across browser restarts.
to verify the downstream behavior i called rememberValidityOverride directly via XPCOM in firefox esr 140.10.0. created a self-signed cert and called it for three hostnames that were never visited with isTemporary=false all three entries showed up in cert_override.txt as permanent overrides with the attacker cert fingerprint. No caller validation at any layer.
I dont have an IPC level reproducer since triggering SendAddCertException requires a compromised content process but the recv handler is a direct passthrough with no validation between the IPC message and the disk write, I can provide the test script and cert_override.txt output if needed.
Verified against mozilla-central tip.
Actual results:
A compromised content process can call SendAddCertException with any hostname, any port, an attacker controlled self signed cert, and isTemporary=false. the parent writes the override to cert_override.txt permanently. No user prompt is shown.
when the user later visits that hostname on a hostile network the attacker presents their cert. firefox checks cert_override.txt, finds the matching fingerprint and accepts the connection. https verification is bypassed without the user ever having approved an exception for that hostname.
This is meant to be callable only from the cert error page UI flow but no enforcement exists in the parent handler.
Expected results:
The parent should not accept cert override requests from content processes without some way to verify the request came from a legitimate cert error page interaction.
Updated•2 months ago
|
Updated•2 months ago
|
Description
•