marky

Lightweight bookmarking + plaintext archive
Log | Files | Refs | README | LICENSE

commit 6508e68df856fefbcccffe44072e82b2f36a9f1b
parent 25defcd00c6af26d1c6cb4e23f784cdd1257465b
Author: David Eisinger <[email protected]>
Date:   Sat, 11 Oct 2025 17:08:51 -0400

Strip more tracking params

Diffstat:
Minternal/api.go | 31+++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/internal/api.go b/internal/api.go @@ -498,8 +498,8 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { http.Error(w, "invalid url", http.StatusBadRequest) return } - // Strip marketing params (utm*) from the URL before processing - sanitizedURL := stripUTMParams(req.URL) + // Strip common tracking params (utm*, gclid, fbclid, etc.) from the URL before processing + sanitizedURL := stripTrackingParams(req.URL) req.URL = sanitizedURL ctx, cancel := context.WithTimeout(r.Context(), 45*time.Second) defer cancel() @@ -856,7 +856,8 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { } } - // Include referrer when provided; otherwise preserve existing value + // Sanitize URL and include referrer when provided; otherwise preserve existing value + req.URL = stripTrackingParams(req.URL) newRef := existing.Referrer.String if req.Referrer != nil { newRef = *req.Referrer @@ -1087,8 +1088,10 @@ func toRespWithArchive(ctx context.Context, db *DB, b *Bookmark) bookmarkRespons return br } -// stripUTMParams removes query parameters whose keys start with "utm" (case-insensitive). -func stripUTMParams(raw string) string { +// stripTrackingParams removes common tracking parameters from a URL's query string. +// It strips keys that start with "utm" (case-insensitive) and a denylist of known trackers +// such as gclid, fbclid, ueid, mc_cid, mc_eid, mkt_tok, _hsmi, _hsenc, igshid, etc. +func stripTrackingParams(raw string) string { u, err := url.Parse(raw) if err != nil { return raw @@ -1098,10 +1101,26 @@ func stripUTMParams(raw string) string { } q := u.Query() changed := false + deny := map[string]struct{}{ + // Google / Facebook / Mailchimp / HubSpot / others + "gclid": {}, "fbclid": {}, "ueid": {}, + "mc_cid": {}, "mc_eid": {}, + "mkt_tok": {}, "_hsmi": {}, "_hsenc": {}, + "igshid": {}, + // common generic trackers + "utm": {}, // handled by prefix match, keep for clarity + } for key := range q { - if len(key) >= 3 && strings.HasPrefix(strings.ToLower(key), "utm") { + lk := strings.ToLower(key) + if strings.HasPrefix(lk, "utm") { + q.Del(key) + changed = true + continue + } + if _, ok := deny[lk]; ok { q.Del(key) changed = true + continue } } if !changed {