cookiebanner: capture script initiator URL on detected trackers

When third-party JS sets a cookie or writes to local/sessionStorage
inside a customer page, the SDK now walks the synchronous call stack
to find the first non-extension, non-Probo, non-first-party http(s)
URL. That origin+path is sent as initiator_url on the report payload,
persisted in a new nullable column on detected_trackers, and preserved
across upserts via COALESCE.

This unlocks per-vendor attribution for cookies and storage writes
without needing pattern name matching, so future categorisation logic
can simply look up the initiator URL in the existing tracker_resources
table and inherit that vendor's category.

GraphQL/MCP exposure is intentionally deferred -- the column is captured
now, surfaced later.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-05-11 10:38:30 +04:00
parent 04fdaed772
commit d17c8ba044
7 changed files with 159 additions and 19 deletions

View File

@@ -35,6 +35,7 @@ type (
MaxAgeSeconds *int `db:"max_age_seconds"`
Source *CookieSource `db:"source"`
ValueSize *int `db:"value_size"`
InitiatorURL *string `db:"initiator_url"`
LastDetectedAt time.Time `db:"last_detected_at"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
@@ -59,6 +60,7 @@ INSERT INTO detected_trackers (
max_age_seconds,
source,
value_size,
initiator_url,
last_detected_at,
created_at,
updated_at
@@ -72,6 +74,7 @@ INSERT INTO detected_trackers (
@max_age_seconds,
@source,
@value_size,
@initiator_url,
@last_detected_at,
@created_at,
@updated_at
@@ -83,6 +86,7 @@ ON CONFLICT (cookie_banner_id, tracker_type, identifier) DO UPDATE
) THEN EXCLUDED.source
ELSE detected_trackers.source
END,
initiator_url = COALESCE(EXCLUDED.initiator_url, detected_trackers.initiator_url),
updated_at = EXCLUDED.updated_at
`
@@ -97,6 +101,7 @@ ON CONFLICT (cookie_banner_id, tracker_type, identifier) DO UPDATE
"source": dt.Source,
"source_script": CookieSourceScript,
"value_size": dt.ValueSize,
"initiator_url": dt.InitiatorURL,
"last_detected_at": dt.LastDetectedAt,
"created_at": dt.CreatedAt,
"updated_at": dt.UpdatedAt,

View File

@@ -0,0 +1,19 @@
-- Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
--
-- Permission to use, copy, modify, and/or distribute this software for any
-- purpose with or without fee is hereby granted, provided that the above
-- copyright notice and this permission notice appear in all copies.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Capture the third-party script URL (origin+path) that triggered a
-- detected cookie or storage write, so the auto-categorisation worker
-- can attribute the artifact to a known vendor via the existing
-- tracker_resources table.
ALTER TABLE detected_trackers ADD COLUMN initiator_url TEXT;