From e2b8ee15e72ff3d996154a561705475ab6044273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Fri, 22 May 2026 14:28:29 +0200 Subject: [PATCH] Track source on detected storage trackers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cookie detector tags every detection with a source (script, pre-existing, http) but the storage detector did not, so storage rows always landed in detected_trackers with source NULL even though the SDK already distinguishes wrapper writes from pre-load scans. Plumb a "script"/"pre-existing" source from the storage detector through the report endpoint into DetectedStorageItem, so the column gets populated for localStorage, sessionStorage, indexedDB and cacheStorage entries. No schema change is needed: detected_trackers already accepts CookieSource values regardless of tracker_type, and the existing row renders the badge as soon as it is non-null. Signed-off-by: Émile Ré --- .../cookie-banner/src/detectors/storage-detector.ts | 12 ++++++++---- packages/cookie-banner/src/detectors/types.ts | 3 +++ pkg/cookiebanner/service.go | 2 ++ pkg/server/api/cookiebanner/v1/handler.go | 11 +++++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/cookie-banner/src/detectors/storage-detector.ts b/packages/cookie-banner/src/detectors/storage-detector.ts index 4361677a5..fbd7a775f 100644 --- a/packages/cookie-banner/src/detectors/storage-detector.ts +++ b/packages/cookie-banner/src/detectors/storage-detector.ts @@ -15,7 +15,7 @@ import type { Detector } from "./detector"; import { getInitiatorURL } from "./initiator"; import type { ReportQueue } from "./report-queue"; -import type { DetectedStorageEntry } from "./types"; +import type { DetectedStorageEntry, StorageSource } from "./types"; const OWN_KEY_PREFIX = "probo_consent:"; const EXTENSION_URL_RE = /(?:chrome|moz|safari-web)-extension:\/\//; @@ -104,7 +104,7 @@ export class StorageDetector implements Detector { const self = this; caches.open = function (name: string): Promise { - self.onCacheStorageOpen(name); + self.onCacheStorageOpen(name, "script"); return originalOpen(name); }; } @@ -122,6 +122,7 @@ export class StorageDetector implements Detector { key, storage_type: storageType, value_size: value.length * 2, + source: "script", }; if (initiatorUrl) entry.initiator_url = initiatorUrl; this.queue.reportStorage(entry); @@ -132,14 +133,16 @@ export class StorageDetector implements Detector { key: name, storage_type: "indexed_db", value_size: null, + source: "script", }); } - private onCacheStorageOpen(name: string): void { + private onCacheStorageOpen(name: string, source: StorageSource): void { this.queue.reportStorage({ key: name, storage_type: "cache_storage", value_size: null, + source, }); } @@ -153,7 +156,7 @@ export class StorageDetector implements Detector { .keys() .then((names) => { for (const name of names) { - this.onCacheStorageOpen(name); + this.onCacheStorageOpen(name, "pre-existing"); } }) .catch(() => { @@ -179,6 +182,7 @@ export class StorageDetector implements Detector { key, storage_type: storageType, value_size: value ? value.length * 2 : null, + source: "pre-existing", }); } } diff --git a/packages/cookie-banner/src/detectors/types.ts b/packages/cookie-banner/src/detectors/types.ts index 191788f68..3e9a9b413 100644 --- a/packages/cookie-banner/src/detectors/types.ts +++ b/packages/cookie-banner/src/detectors/types.ts @@ -19,6 +19,8 @@ export type CookieSource = "script" | "pre-existing" | "http"; +export type StorageSource = "script" | "pre-existing"; + export type StorageType = | "local_storage" | "session_storage" @@ -47,6 +49,7 @@ export interface DetectedStorageEntry { key: string; storage_type: StorageType; value_size: number | null; + source: StorageSource; initiator_url?: string; } diff --git a/pkg/cookiebanner/service.go b/pkg/cookiebanner/service.go index 30e09bcbe..0aa6d5164 100644 --- a/pkg/cookiebanner/service.go +++ b/pkg/cookiebanner/service.go @@ -123,6 +123,7 @@ type ( Key string StorageType coredata.TrackerType ValueSize *int + Source *coredata.CookieSource InitiatorURL *string } @@ -2124,6 +2125,7 @@ func (s *Service) ReportDetectedTrackers( TrackerType: ds.StorageType, Identifier: ds.Key, ValueSize: ds.ValueSize, + Source: ds.Source, InitiatorURL: ds.InitiatorURL, }, &inserted, diff --git a/pkg/server/api/cookiebanner/v1/handler.go b/pkg/server/api/cookiebanner/v1/handler.go index a80028899..9d84b8911 100644 --- a/pkg/server/api/cookiebanner/v1/handler.go +++ b/pkg/server/api/cookiebanner/v1/handler.go @@ -383,6 +383,7 @@ type detectedStorageEntry struct { Key string `json:"key"` StorageType string `json:"storage_type"` ValueSize *int `json:"value_size"` + Source string `json:"source"` InitiatorURL *string `json:"initiator_url,omitempty"` } @@ -474,12 +475,22 @@ func (h *Handler) handleReportDetectedTrackers(w http.ResponseWriter, r *http.Re continue } + var source coredata.CookieSource + + switch strings.TrimSpace(s.Source) { + case "pre-existing": + source = coredata.CookieSourcePreExisting + default: + source = coredata.CookieSourceScript + } + req.Storage = append( req.Storage, cookiebanner.DetectedStorageItem{ Key: key, StorageType: storageType, ValueSize: s.ValueSize, + Source: &source, InitiatorURL: sanitizeInitiatorURL(s.InitiatorURL), }, )