IPC Sandbox Escape - RecvAddCertException + Systemic Missing Validation
Categories
(Core :: DOM: Content Processes, defect)
Tracking
()
People
(Reporter: ikkibr, Unassigned)
References
()
Details
(Keywords: ai-involved, reporter-external, Whiteboard: [client-bounty-form])
Product: Firefox 150
OS: Windows / Linux
Hardware: All
Summary
A compromised content process can call SendAddCertException with an arbitrary hostname to permanently add TLS certificate overrides for any site, enabling MITM attacks. Additionally, LogAndAssertFailedPrincipalValidationInfo — the enforcement mechanism for principal validation across 29 IPC handlers — only asserts in DEBUG builds and silently continues in release Firefox.
Primary Finding: RecvAddCertException (ContentParent.cpp:6604)
The handler accepts aHostName directly from the content process and passes it to nsICertOverrideService::RememberValidityOverride without any validation:
mozilla::ipc::IPCResult ContentParent::RecvAddCertException(
nsIX509Cert* aCert, const nsACString& aHostName, int32_t aPort,
const OriginAttributes& aOriginAttributes, bool aIsTemporary,
AddCertExceptionResolver&& aResolver) {
// ...
nsresult rv = overrideService->RememberValidityOverride(
aHostName, aPort, aOriginAttributes, aCert, aIsTemporary);
// NO hostname validation, NO principal check, NO origin check
}
The web-exposed API (Document::AddCertException) correctly restricts the hostname to the failed channel's URI via CallerIsTrustedAboutCertError. A compromised content process bypasses this entirely.
Compare with the next handler at L6621, which validates its principal:
mozilla::ipc::IPCResult ContentParent::RecvAutomaticStorageAccessPermissionCanBeGranted(
nsIPrincipal* aPrincipal, ...) {
if (!ValidatePrincipal(aPrincipal)) { // <-- validates
LogAndAssertFailedPrincipalValidationInfo(aPrincipal, __func__);
}
}
Systemic Finding: LogAndAssertFailedPrincipalValidationInfo (L1296)
void ContentParent::LogAndAssertFailedPrincipalValidationInfo(...) {
// ... telemetry + logging ...
#ifdef DEBUG
MOZ_ASSERT(false, "Receiving unexpected Principal"); // DEBUG ONLY
#endif
// In release: returns, execution continues
}
This function is called at 29 sites when ValidatePrincipal fails. In release builds, it's a no-op — the invalid principal is accepted and the IPC handler continues with the untrusted data.
Example — RecvSetClipboard (L3197):
if (!ValidatePrincipal(aTransferable.dataPrincipal(),
{AllowNullPtr, AllowExpanded, AllowSystem})) {
LogAndAssertFailedPrincipalValidationInfo(...);
// NO RETURN — falls through to clipboard->SetData() in release
}
Additional Unvalidated Handlers
| Handler | Line | Risk |
|---|---|---|
RecvLoadURIExternal |
L4674 | Unvalidated principals for external protocol launch |
RecvPContentPermissionRequestConstructor |
L5175 | Spoofed principal + fake user gesture → permission prompts |
RecvBlobURLDataRequest |
L7456 | Unvalidated principals → cross-origin blob access |
RecvCreateWindowInDifferentProcess |
L5575 | Unvalidated principal (peer RecvCreateWindow validates) |
RecvPExternalHelperAppConstructor |
L4570 | No validation on URI/MIME/filename |
RecvSetURITitle |
L4634 | History poisoning — set titles for any URI |
RecvStartVisitedQueries |
L4619 | History probing — query visited status of any URI |
RecvStorageAccessPermissionGrantedForOrigin |
L6636 | Bypass anti-tracking for arbitrary origins |
RecvSyncMessage / RecvAsyncMessage |
L4726/L4740 | No message name or content filtering |
Attack Scenario
- Attacker achieves code execution in content process (e.g., JIT type confusion)
- Compromised process calls
SendAddCertException("victim-bank.com", 443, ..., attacker_cert, false) - Parent process permanently stores the cert override
- User visits victim-bank.com → attacker's cert accepted silently
- Full MITM of the session
Suggested Fixes
- RecvAddCertException: Validate that the content process currently has a cert error for
aHostName, mirroring theDocument::AddCertExceptioncheck - LogAndAssertFailedPrincipalValidationInfo: Return
IPC_FAILinstead of continuing on validation failure, or at minimum addMOZ_RELEASE_ASSERT - All Recv handlers accepting principals: Add
ValidatePrincipalcalls
Comment 1•4 months ago
|
||
This is a privilege escalation (using a specific capability content processes shouldn't have), but that doesn't make it a sandbox escape
Comment 2•4 months ago
|
||
Ugh, this is a dozen bugs reported as one. Only the first is a dupe of bug 2013800. Please study our Bug Writing Guidelines where the first exhortation is "Open a new bug report for each issue!" -- but pay attention to the rest, too, of course.
The other APIs are likely dupes also. This looks like AI-tool reports and those resulted in 5 dupes of 2013800 so the same tools probably keep finding the others.
Updated•4 months ago
|
Comment 3•4 months ago
|
||
I'd just leave it as a dupe of something. I think it is all on file and we aren't really trying to enforce this anyways.
Updated•4 months ago
|
Updated•4 months ago
|
Updated•4 months ago
|
Updated•4 months ago
|
Comment 5•2 months ago
|
||
Looks like this is the first mention of a lack of validation of ContentParent::RecvStartVisitedQueries.
Updated•2 months ago
|
Description
•