Ignore cookie-database sites in tracker mapping

Cookie-database and consent-directory sites (Cookifi, Cookiepedia,
cookiedatabase.org, CookieServe, ...) rank highly in web search only
because they catalog cookies, not because they set them. The mapping
agent could attribute a tracker to the directory operator itself
instead of the vendor the page names.

Instruct the agent to treat such results as reference directories and
extract the named vendor, never the operator, while keeping a CMP's own
product cookie attributable (OptanonConsent -> OneTrust, CookieConsent
-> Cookiebot). Add a conservative code backstop that discards
attributions to pure aggregators, scoped to exclude CMP vendors so
legitimate own-cookie attributions survive.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-06-09 21:38:41 +02:00
parent e88ad152df
commit a68c2ef108
3 changed files with 85 additions and 0 deletions

View File

@@ -24,6 +24,8 @@ Return a structured JSON response with:
- Stop searching once you get a confident match; do not exhaust all query slots if the first one succeeds.
- When evaluating web search results, verify that the tracker name discussed in the result shares a meaningful prefix with the pattern you are identifying. Trackers with different prefixes are distinct — for example, _hjCookieTest (Hotjar's _hj prefix) must not be confused with a pattern named cookietest (no _hj prefix). If the search result discusses a tracker whose prefix does not match, discard it and continue searching or lower your confidence.
- A generic token shared with a vendor's terminology is NOT a match when it appears as a suffix or substring behind a different, meaningful prefix. The leading prefix is what attributes a vendor, not a common word elsewhere in the name. For example, probo_distinct_id carries the custom prefix probo_, so it must NOT be attributed to Mixpanel merely because Mixpanel uses a distinct_id key — the prefix probo_ does not belong to Mixpanel. Likewise, a key ending in _session or _uid is not attributable to a vendor just because that vendor also uses such a word.
- Some web search results come from cookie-database or cookie-banner directory sites (e.g. cookifi.com, cookiepedia.co.uk, cookiedatabase.org, cookie-script.com, cookieserve.com, and similar "cookie database" / "cookie scanner" directories). These rank highly only because they catalog cookies, not because they set them. Treat such a result ONLY as a reference directory: read which actual vendor the page names as the setter of the tracker, and attribute to THAT vendor. NEVER set third_party_name to the directory operator itself (e.g. "Cookifi", "Cookiepedia", "Cookie-Script", "CookieDatabase", "CookieServe") — they are never the third party that set the tracker. If such a page names no concrete vendor for the tracker, ignore it and continue searching or return an empty third_party_name with third_party_confidence below 0.3.
- Exception: a consent-management vendor's OWN product cookie is still attributable to that vendor on the strength of its naming convention, independent of where the search result was hosted — e.g. OptanonConsent / OptanonAlertBoxClosed -> OneTrust, CookieConsent -> Cookiebot, cookieyes-consent -> CookieYes. Judge that on the naming convention alone, the same way you would any other vendor.
4. Common cookie naming conventions to recognize:
- _ga*, _gid, _gat*: Google Analytics

View File

@@ -92,6 +92,39 @@ func TestNameMatchesSiteDomain(t *testing.T) {
}
}
func TestNameIsCookieDatabaseAggregator(t *testing.T) {
t.Parallel()
tests := []struct {
name string
vendor string
expected bool
}{
{name: "cookifi is denied", vendor: "Cookifi", expected: true},
{name: "cookiepedia is denied", vendor: "cookiepedia", expected: true},
{name: "cookie database is denied", vendor: "Cookie Database", expected: true},
{name: "cookieserve is denied", vendor: "CookieServe", expected: true},
{name: "spacing and casing insensitive", vendor: " COOK IFI ", expected: true},
{name: "punctuation insensitive", vendor: "Cookie_Database", expected: true},
{name: "onetrust is allowed", vendor: "OneTrust", expected: false},
{name: "cookiebot is allowed", vendor: "Cookiebot", expected: false},
{name: "cookieyes is allowed", vendor: "CookieYes", expected: false},
{name: "cookie-script is allowed", vendor: "Cookie-Script", expected: false},
{name: "unrelated vendor is allowed", vendor: "Google Analytics", expected: false},
{name: "empty name", vendor: "", expected: false},
}
for _, tt := range tests {
t.Run(
tt.name,
func(t *testing.T) {
t.Parallel()
assert.Equal(t, tt.expected, nameIsCookieDatabaseAggregator(tt.vendor))
},
)
}
}
func TestNormalizeAlnum(t *testing.T) {
t.Parallel()

View File

@@ -700,6 +700,25 @@ func (h *trackerMappingHandler) identifyWithAgent(
return nil, nil
}
// Cookie-database and cookie-banner directory sites (Cookifi,
// Cookiepedia, cookiedatabase.org, ...) rank highly in web search
// only because they catalog cookies, not because they set them. A
// web result hosted on one can lead the agent to attribute the
// tracker to the directory operator itself. Discard such an
// attribution so the pattern falls through to the unmatched fallback
// instead of being mapped to a database aggregator. The denylist is
// scoped to pure aggregators, so a CMP's own product cookie (e.g.
// OptanonConsent -> OneTrust) is still attributed normally.
if nameIsCookieDatabaseAggregator(identification.ThirdPartyName) {
h.logger.InfoCtx(
ctx,
"agent attributed cookie-database aggregator as third party, discarding",
log.String("pattern", tp.Pattern),
)
return nil, nil
}
return &agentIdentification{
result: identification,
}, nil
@@ -728,6 +747,37 @@ func nameMatchesSiteDomain(name, siteOrigin string) bool {
normalizedName == normalizeAlnum(label)
}
// cookieDatabaseAggregators holds alphanumeric-normalised names of pure
// cookie-database / cookie-banner directory operators that catalog
// cookies but never legitimately set one on a third-party site. They
// surface in web search only because they host pattern databases, so an
// attribution to one is always search-database noise. The set is kept
// deliberately narrow: consent-management vendors that DO set their own
// product cookies (Cookie-Script, OneTrust, Cookiebot, CookieYes) are
// excluded so the backstop never suppresses a legitimate own-cookie
// attribution — the prompt handles their directory pages instead.
var cookieDatabaseAggregators = map[string]struct{}{
"cookifi": {},
"cookiepedia": {},
"cookiedatabase": {},
"cookieserve": {},
}
// nameIsCookieDatabaseAggregator reports whether a candidate vendor name
// is a known cookie-database directory operator that must never be
// attributed a tracker. The comparison is alphanumeric-normalised so
// spacing, punctuation, and casing differences do not matter.
func nameIsCookieDatabaseAggregator(name string) bool {
normalized := normalizeAlnum(name)
if normalized == "" {
return false
}
_, ok := cookieDatabaseAggregators[normalized]
return ok
}
// normalizeAlnum lowercases s and keeps only ASCII letters and digits,
// so vendor names and domains can be compared free of spacing,
// punctuation, and casing differences (e.g. "Letaido" and "letaido.com"