commit f876fc136a22d1ec693fd4207fc4ec02f56925ae
parent 76464d08572d04c7f1ad0516008b2efb9c7f5a69
Author: Tom Ritter <tom@mozilla.com>
Date: Mon, 8 Dec 2025 16:31:02 +0000
Bug 1873716: Handle about:blank iframes that do fingerprinting r=timhuang
We encountered a fingerprinter that created an about:blank iframe
and did fingerprinting there. This iframe had no channel, so it
did not get a ContentBlockingEvent on it. Traverse the document
tree upwards to find a document we can log it on.
SKIP_BMO_CHECK
Differential Revision: https://phabricator.services.mozilla.com/D274380
Diffstat:
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp
@@ -17600,7 +17600,6 @@ void Document::RecordCanvasUsage(CanvasUsage& aUsage) {
uint64_t now = PR_Now();
-
nsCString originNoSuffix;
nsCString uri;
if (NS_FAILED(NodePrincipal()->GetOriginNoSuffix(originNoSuffix))) {
@@ -17662,6 +17661,50 @@ void Document::RecordCanvasUsage(CanvasUsage& aUsage) {
mCanvasUsageLastTimestamp = now;
mCanvasUsageData.AppendElement(aUsage);
+ nsIChannel* channel = GetChannel();
+ if (!channel) {
+ MOZ_LOG(
+ gFingerprinterDetection, LogLevel::Warning,
+ ("Document:: %p %s no channel available", this, originNoSuffix.get()));
+
+ // Borrowed from ReComputeResistFingerprinting
+ // which tells me this is probably a common problem...
+ auto shouldInheritFrom = [this](Document* aDoc) {
+ return aDoc && this->NodePrincipal() &&
+ (this->NodePrincipal()->Equals(aDoc->NodePrincipal()) ||
+ this->NodePrincipal()->GetIsNullPrincipal());
+ };
+
+ // Climb parent documents until we find a channel.
+ Document* docToCheck = this;
+ while (docToCheck && !channel) {
+ if (docToCheck->mParentDocument &&
+ shouldInheritFrom(docToCheck->mParentDocument)) {
+ channel = docToCheck->mParentDocument->GetChannel();
+ }
+ docToCheck = docToCheck->mParentDocument;
+ }
+
+ docToCheck = this;
+ while (docToCheck && !channel) {
+ RefPtr<BrowsingContext> opener =
+ docToCheck->GetBrowsingContext()
+ ? docToCheck->GetBrowsingContext()->GetOpener()
+ : nullptr;
+ docToCheck = opener ? opener->GetDocument() : nullptr;
+
+ if (docToCheck && shouldInheritFrom(docToCheck)) {
+ channel = docToCheck->GetChannel();
+ }
+ }
+
+ if (!channel) {
+ MOZ_LOG(gFingerprinterDetection, LogLevel::Warning,
+ ("Document:: %p %s still could not find a channel", this,
+ originNoSuffix.get()));
+ }
+ }
+
nsRFPService::MaybeReportCanvasFingerprinter(mCanvasUsageData, channel, uri,
originNoSuffix);
}