RecvAddCertException: no validation of child-supplied hostname
Categories
(Core :: DOM: Content Processes, defect)
Tracking
()
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.
Updated•3 months ago
|
Updated•3 months ago
|
Updated•2 months ago
|
Description
•