Five WindowGlobalParent IPC handlers accept content-process values with no validation -- sandbox escape, TLS forgery, CSP/HTTPS-Only/tracking protection bypass
Categories
(Core :: DOM: Content Processes, defect)
Tracking
()
People
(Reporter: lorenzoauto311, Unassigned)
References
()
Details
(Keywords: ai-involved, reporter-external, Whiteboard: [client-bounty-form])
I was going through the IPC handlers in dom/ipc/WindowGlobalParent.cpp and noticed that several of them take security-critical values from the content process and store them directly in parent-process state without any checks.
Here are the five handlers, all following the exact same pattern:
- RecvUpdateDocumentSecurityInfo (WindowGlobalParent.cpp:743-747)
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateDocumentSecurityInfo(
nsITransportSecurityInfo* aSecurityInfo) {
mSecurityInfo = aSecurityInfo;
return IPC_OK();
}
This one is probably the worst. mSecurityInfo is what WindowGlobalParent::GetSecurityInfo() returns (declared at WindowGlobalParent.h:223), and the browser UI reads that to show the padlock icon and certificate details. A compromised content process can fabricate an nsITransportSecurityInfo and send it here, making a plaintext HTTP page show a valid HTTPS padlock with whatever certificate it wants. Straight phishing vector.
- RecvUpdateSandboxFlags (WindowGlobalParent.cpp:530-533)
IPCResult WindowGlobalParent::RecvUpdateSandboxFlags(uint32_t aSandboxFlags) {
mSandboxFlags = aSandboxFlags;
return IPC_OK();
}
A compromised content process in a sandboxed iframe sends aSandboxFlags = 0 and all sandbox restrictions disappear -- scripts, popups, form submission, top-navigation, everything. The parent never verifies the new flags are at least as restrictive as the original <iframe sandbox> attribute. One IPC message to escape the sandbox.
- RecvUpdateDocumentCspSettings (WindowGlobalParent.cpp:535-540)
IPCResult WindowGlobalParent::RecvUpdateDocumentCspSettings(
bool aBlockAllMixedContent, bool aUpgradeInsecureRequests) {
mBlockAllMixedContent = aBlockAllMixedContent;
mUpgradeInsecureRequests = aUpgradeInsecureRequests;
return IPC_OK();
}
Send both as false and mixed content blocking + upgrade-insecure-requests get turned off for that window.
- RecvUpdateHttpsOnlyStatus (WindowGlobalParent.cpp:512-516)
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateHttpsOnlyStatus(
uint32_t aHttpsOnlyStatus) {
mHttpsOnlyStatus = aHttpsOnlyStatus;
return IPC_OK();
}
The field is a bitmask of nsILoadInfo::HTTPS_ONLY_* flags (nsILoadInfo.idl:495-548). Send 0 or HTTPS_ONLY_EXEMPT and HTTPS-Only mode is disabled for this window even though the user turned it on in settings.
- RecvUpdateCookieJarSettings (WindowGlobalParent.cpp:736-741)
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateCookieJarSettings(
const CookieJarSettingsArgs& aCookieJarSettingsArgs) {
net::CookieJarSettings::Deserialize(aCookieJarSettingsArgs,
getter_AddRefs(mCookieJarSettings));
return IPC_OK();
}
This one deserializes the entire CookieJarSettingsArgs struct (NeckoChannelParams.ipdlh:63-73) from content. Every field is attacker-controlled: cookieBehavior, isFirstPartyIsolated, shouldResistFingerprinting, isOnContentBlockingAllowList, cookiePermissions, etc. Set cookieBehavior to BEHAVIOR_ACCEPT and isOnContentBlockingAllowList to true and you've killed Enhanced Tracking Protection and Total Cookie Protection for that window.
All five are declared with [LazySend] in PWindowGlobal.ipdl, no validation annotations in the IPDL definitions either.
For comparison, other handlers in the same file DO validate. RecvUpdateDocumentPrincipal (line 463) checks Equals(), RecvSetDocumentDomain (line 1401) has IsValidDomain(). These five were apparently missed.
Actual results:
A compromised content process can forge the URL bar padlock/certificate, escape iframe sandboxing, disable CSP mixed content blocking, bypass HTTPS-Only mode, and turn off cookie/tracking protections -- all with single IPC messages that the parent process accepts without question.
Expected results:
Each handler should validate the incoming value against the parent's known state from the original document load:
- SecurityInfo: should only be set during document load, never updatable from content after that.
- SandboxFlags: new flags must be a superset of existing flags (only allow tightening). Return IPC_FAIL if content tries to drop flags.
- CSP settings: only allow setting to true, never back to false.
- HttpsOnlyStatus: only allow tightening.
- CookieJarSettings: should not be overridable from content at all, or only toward stricter settings.
Any violation should return IPC_FAIL to kill the content process.
Tested against current mozilla-central. These are sandbox escape / security bypass bugs exploitable from a compromised content process.
Comment 1•8 months ago
|
||
It is a bit confusing to have a bunch of issues filed together. In this case, it looks like these are all duplicates of bugs we already have on file.
(In reply to Lorenzo from comment #0)
- RecvUpdateDocumentSecurityInfo (WindowGlobalParent.cpp:743-747)
- RecvUpdateSandboxFlags (WindowGlobalParent.cpp:530-533)
- RecvUpdateDocumentCspSettings (WindowGlobalParent.cpp:535-540)
- RecvUpdateHttpsOnlyStatus (WindowGlobalParent.cpp:512-516)
Hmm this one I don't see this one exactly, but I expect it is conceptually kind of a dupe of bug 2014104 which we closed.
- RecvUpdateCookieJarSettings (WindowGlobalParent.cpp:736-741)
Updated•8 months ago
|
Updated•8 months ago
|
Updated•1 month ago
|
Description
•