Report full URL instead of bare origin for detected scripts and iframes
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é <emile@getprobo.com>
This commit is contained in:
@@ -17,7 +17,7 @@ import { NotFoundError } from "../errors";
|
|||||||
import { fetchJSON } from "../http";
|
import { fetchJSON } from "../http";
|
||||||
|
|
||||||
interface DetectedResourceEntry {
|
interface DetectedResourceEntry {
|
||||||
origin: string;
|
url: string;
|
||||||
resource_type: "script" | "iframe";
|
resource_type: "script" | "iframe";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,20 +105,21 @@ export class ThirdPartyDetector implements Detector {
|
|||||||
private processElement(src: string, resourceType: "script" | "iframe"): void {
|
private processElement(src: string, resourceType: "script" | "iframe"): void {
|
||||||
if (EXTENSION_URL_RE.test(src)) return;
|
if (EXTENSION_URL_RE.test(src)) return;
|
||||||
|
|
||||||
let origin: string;
|
let parsed: URL;
|
||||||
try {
|
try {
|
||||||
origin = new URL(src).origin;
|
parsed = new URL(src);
|
||||||
} catch {
|
} catch {
|
||||||
return;
|
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;
|
if (this.reported.has(reportKey)) return;
|
||||||
|
|
||||||
this.reported.add(reportKey);
|
this.reported.add(reportKey);
|
||||||
this.pending.set(reportKey, { origin, resource_type: resourceType });
|
this.pending.set(reportKey, { url: identifier, resource_type: resourceType });
|
||||||
this.scheduleFlush();
|
this.scheduleFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/coredata"
|
"go.probo.inc/probo/pkg/coredata"
|
||||||
"go.probo.inc/probo/pkg/gid"
|
"go.probo.inc/probo/pkg/gid"
|
||||||
"go.probo.inc/probo/pkg/page"
|
"go.probo.inc/probo/pkg/page"
|
||||||
|
"go.probo.inc/probo/pkg/uri"
|
||||||
"go.probo.inc/probo/pkg/validator"
|
"go.probo.inc/probo/pkg/validator"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -125,7 +126,7 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
DetectedResourceItem struct {
|
DetectedResourceItem struct {
|
||||||
Origin string
|
URL uri.URI
|
||||||
ResourceType coredata.TrackerType
|
ResourceType coredata.TrackerType
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1992,7 +1993,7 @@ func (s *Service) ReportDetectedTrackers(
|
|||||||
now,
|
now,
|
||||||
detectedTrackerInfo{
|
detectedTrackerInfo{
|
||||||
TrackerType: dr.ResourceType,
|
TrackerType: dr.ResourceType,
|
||||||
Identifier: dr.Origin,
|
Identifier: dr.URL.String(),
|
||||||
},
|
},
|
||||||
&inserted,
|
&inserted,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/gid"
|
"go.probo.inc/probo/pkg/gid"
|
||||||
"go.probo.inc/probo/pkg/server/api/clientip"
|
"go.probo.inc/probo/pkg/server/api/clientip"
|
||||||
"go.probo.inc/probo/pkg/server/jsonutil"
|
"go.probo.inc/probo/pkg/server/jsonutil"
|
||||||
|
"go.probo.inc/probo/pkg/uri"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
@@ -309,8 +310,8 @@ type detectedStorageEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type detectedResourceEntry struct {
|
type detectedResourceEntry struct {
|
||||||
Origin string `json:"origin"`
|
URL uri.URI `json:"url"`
|
||||||
ResourceType string `json:"resource_type"`
|
ResourceType string `json:"resource_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type reportDetectedTrackersBody struct {
|
type reportDetectedTrackersBody struct {
|
||||||
@@ -400,11 +401,6 @@ func (h *Handler) handleReportDetectedTrackers(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, res := range body.Resources {
|
for _, res := range body.Resources {
|
||||||
origin := strings.TrimSpace(res.Origin)
|
|
||||||
if origin == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourceType coredata.TrackerType
|
var resourceType coredata.TrackerType
|
||||||
switch strings.TrimSpace(res.ResourceType) {
|
switch strings.TrimSpace(res.ResourceType) {
|
||||||
case "script":
|
case "script":
|
||||||
@@ -418,7 +414,7 @@ func (h *Handler) handleReportDetectedTrackers(w http.ResponseWriter, r *http.Re
|
|||||||
req.Resources = append(
|
req.Resources = append(
|
||||||
req.Resources,
|
req.Resources,
|
||||||
cookiebanner.DetectedResourceItem{
|
cookiebanner.DetectedResourceItem{
|
||||||
Origin: origin,
|
URL: res.URL,
|
||||||
ResourceType: resourceType,
|
ResourceType: resourceType,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user