Parent History IPC Exposes Browsing History to Compromised Content
Categories
(Core :: CSS Parsing and Computation, defect)
Tracking
()
People
(Reporter: geeknik, Unassigned)
References
Details
(Keywords: reporter-external, sec-want, Whiteboard: [client-bounty-form])
Attachments
(1 file)
|
2.38 KB,
patch
|
Details | Diff | Splinter Review |
Summary
PContent::StartVisitedQueries lets a content process send arbitrary URIs to the parent process. The parent passes those URIs to the Places history service and sends visited/not-visited results back to the same content process with NotifyVisited.
Under the Firefox sandbox threat model, compromised content can call the generated ContentChild::SendStartVisitedQueries(...) method directly and use the parent process as a browsing-history oracle.
Affected Code
- IPC declaration:
dom/ipc/PContent.ipdlasync StartVisitedQueries(nullable nsIURI[] uri);async NotifyVisited(VisitedQueryResult[] uri);
- Parent handler:
dom/ipc/ContentParent.cppContentParent::RecvStartVisitedQueries(...)- Calls
history->ScheduleVisitedQuery(uri, this)for each content-supplied URI.
- History dispatch:
docshell/base/BaseHistory.cppBaseHistory::ScheduleVisitedQuery(...)records the requestingContentParent.BaseHistory::NotifyVisitedFromParent(...)queuesVisitedQueryResult.BaseHistory::SendPendingVisitedResultsToChildProcesses(...)sends the result to the interested content process.
- Places query:
toolkit/components/places/History.cppHistory::QueueVisitedStatement(...)queriesmoz_placesand returnslast_visit_date NOTNULL.
- Content receiver:
dom/ipc/ContentChild.cppContentChild::RecvNotifyVisited(...)receives the parent result.
PoC
Create a profile with a known visited URL:
rm -rf /tmp/fx-history-poc-profile
mkdir -p /tmp/fx-history-poc-profile
./mach run --profile /tmp/fx-history-poc-profile https://example.com/
Wait for the page to load, then quit Firefox.
Apply the attached patch:
git apply history-ipc-poc.patch
./mach build binaries
Run Firefox with the content-process PoC enabled:
MOZ_POC_HISTORY_IPC=1 \
MOZ_POC_HISTORY_IPC_URL=https://example.com/ \
MOZ_POC_HISTORY_IPC_URL2=https://example.invalid/ \
./mach run --profile /tmp/fx-history-poc-profile https://mozilla.org/
Expected stderr from the content process:
MOZ_POC_HISTORY_IPC: sending 2 visited query request(s)
MOZ_POC_HISTORY_IPC result: visited=1 uri=https://example.com/
MOZ_POC_HISTORY_IPC result: visited=0 uri=https://example.invalid/
The PoC does not use CSS :visited, DOM link styling, or web-exposed history APIs. It calls ContentChild::SendStartVisitedQueries(...) directly from content-process C++ and prints the parent's NotifyVisited response.
Impact
Compromised web content can query whether arbitrary URLs are present in the user's browser history. This exposes parent-held browsing history across the sandbox boundary.
Expected Fix
The parent should not answer arbitrary visited queries sent by content. If this IPC must exist for link styling, the parent should bind requests to actual link elements/documents owned by the sending process and avoid returning raw visited state to compromised content-controlled code.
Updated•2 months ago
|
Comment 2•2 months ago
|
||
For purposes of the bug bounty this is a duplicate, but it will be more useful and less confusing to reopen this for the specific issue of RecvStartVisitedQueries. The bug this was duped to was a multi-issue mess and itself was duped to only one of them.
Updated•21 days ago
|
Comment 5•21 days ago
|
||
Maybe we can come up with a more specific component than DOM: Content Processes for this? Bug 1714614 was in CSS so I'll move this there. Feel free to adjust as appropriate.
Comment 6•16 days ago
|
||
The parent should not answer arbitrary visited queries sent by content. If this IPC must exist for link styling, the parent should bind requests to actual link elements/documents owned by the sending process and avoid returning raw visited state to compromised content-controlled code.
How would that work exactly? I don't think this is particularly actionable. Can't a compromised content process basically create a link using script? How would the parent detect that? Let me know if I'm missing something but this seems unfixable other than by partitioning :visited which is covered by bug 1398414.
Please sanity-check me and reopening if I'm missing something tho.
Description
•