From a4cb61366fddcb69f2f7ade49a0af2976cd0a4a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Wed, 6 May 2026 18:34:12 +0400 Subject: [PATCH] Report full URL instead of bare origin for detected scripts and iframes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strip query params and send origin+pathname so the backend can distinguish resources served from the same domain but different paths (e.g. gtm.js vs recaptcha/api.js on googletagmanager.com). Signed-off-by: Émile Ré --- .../src/detectors/third-party-detector.ts | 13 +++++++------ pkg/cookiebanner/service.go | 5 +++-- pkg/server/api/cookiebanner/v1/handler.go | 12 ++++-------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/cookie-banner/src/detectors/third-party-detector.ts b/packages/cookie-banner/src/detectors/third-party-detector.ts index 7b9cb162e..8ff656196 100644 --- a/packages/cookie-banner/src/detectors/third-party-detector.ts +++ b/packages/cookie-banner/src/detectors/third-party-detector.ts @@ -17,7 +17,7 @@ import { NotFoundError } from "../errors"; import { fetchJSON } from "../http"; interface DetectedResourceEntry { - origin: string; + url: string; resource_type: "script" | "iframe"; } @@ -105,20 +105,21 @@ export class ThirdPartyDetector implements Detector { private processElement(src: string, resourceType: "script" | "iframe"): void { if (EXTENSION_URL_RE.test(src)) return; - let origin: string; + let parsed: URL; try { - origin = new URL(src).origin; + parsed = new URL(src); } catch { return; } - if (origin === this.pageOrigin || origin === this.proboOrigin) return; + if (parsed.origin === this.pageOrigin || parsed.origin === this.proboOrigin) return; - const reportKey = `${resourceType}:${origin}`; + const identifier = parsed.origin + parsed.pathname; + const reportKey = `${resourceType}:${identifier}`; if (this.reported.has(reportKey)) return; this.reported.add(reportKey); - this.pending.set(reportKey, { origin, resource_type: resourceType }); + this.pending.set(reportKey, { url: identifier, resource_type: resourceType }); this.scheduleFlush(); } diff --git a/pkg/cookiebanner/service.go b/pkg/cookiebanner/service.go index ca8e22de3..f0f90a83a 100644 --- a/pkg/cookiebanner/service.go +++ b/pkg/cookiebanner/service.go @@ -30,6 +30,7 @@ import ( "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/page" + "go.probo.inc/probo/pkg/uri" "go.probo.inc/probo/pkg/validator" ) @@ -125,7 +126,7 @@ type ( } DetectedResourceItem struct { - Origin string + URL uri.URI ResourceType coredata.TrackerType } @@ -1992,7 +1993,7 @@ func (s *Service) ReportDetectedTrackers( now, detectedTrackerInfo{ TrackerType: dr.ResourceType, - Identifier: dr.Origin, + Identifier: dr.URL.String(), }, &inserted, ); err != nil { diff --git a/pkg/server/api/cookiebanner/v1/handler.go b/pkg/server/api/cookiebanner/v1/handler.go index 7e4b46b14..108d1dc7e 100644 --- a/pkg/server/api/cookiebanner/v1/handler.go +++ b/pkg/server/api/cookiebanner/v1/handler.go @@ -31,6 +31,7 @@ import ( "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/server/api/clientip" "go.probo.inc/probo/pkg/server/jsonutil" + "go.probo.inc/probo/pkg/uri" ) type Handler struct { @@ -309,8 +310,8 @@ type detectedStorageEntry struct { } type detectedResourceEntry struct { - Origin string `json:"origin"` - ResourceType string `json:"resource_type"` + URL uri.URI `json:"url"` + ResourceType string `json:"resource_type"` } type reportDetectedTrackersBody struct { @@ -400,11 +401,6 @@ func (h *Handler) handleReportDetectedTrackers(w http.ResponseWriter, r *http.Re } for _, res := range body.Resources { - origin := strings.TrimSpace(res.Origin) - if origin == "" { - continue - } - var resourceType coredata.TrackerType switch strings.TrimSpace(res.ResourceType) { case "script": @@ -418,7 +414,7 @@ func (h *Handler) handleReportDetectedTrackers(w http.ResponseWriter, r *http.Re req.Resources = append( req.Resources, cookiebanner.DetectedResourceItem{ - Origin: origin, + URL: res.URL, ResourceType: resourceType, }, )