Bug-ul
Pe o platformă SaaS B2B multi-tenant care ține facturi și datele clienților, tag-ul de analytics colecta automat e-mailul, telefonul și adresa poștală din formulare, cu mascarea datelor oprită. Rula înainte ca cineva să accepte cookie-urile, iar vizitatorii nu aveau cum să refuze tracking-ul. În aplicație, un pixel de reclame primea copii hash-uite ale e-mailului și telefonului operatorului și le păstra într-un cookie timp de doi ani.
Cum se vede
Pe ecran, deloc. Formularele mergeau și paginile se încărcau. Datele plecau în cereri din fundal pe care nu le urmărea nimeni. Multe echipe mai cred și că hash-uit înseamnă anonim. Platformele de reclame hash-uiesc e-mailurile și numerele de telefon tocmai ca să le potrivească cu oameni.
Cum l-am găsit
În același audit de securitate am deschis platforma într-un browser curat, n-am acceptat nimic, am completat un formular cu datele noastre de test și am citit traficul de rețea. Datele de contact tastate plecau la furnizorul de analytics. Am notat ce se trimite și ne-am oprit acolo, fără să schimbăm ceva și fără să atingem datele altcuiva.
Reparația
Ce am recomandat: colectarea automată a datelor personale se oprește din setările de analytics și se pornește mascarea. Analytics-ul și pixelul de reclame se încarcă doar după ce vizitatorul își dă consimțământul, iar vizitatorul primește un buton care refuză tracking-ul.
Testul care îl prinde
Un test Playwright pornește cu un profil de browser nou, fără consimțământ. Completează un formular, apoi verifică faptul că nicio cerere către un domeniu de analytics sau de reclame nu conține e-mailul sau telefonul tastat, nici în clar, nici ca hash SHA-256, și că nu se setează niciun cookie de tracking înainte de consimțământ. Rulează în CI la fiecare release.
import { test, expect } from "@playwright/test";
import { createHash } from "node:crypto";
import { TRACKER_DOMAINS, TRACKING_COOKIES } from "./trackers";
const email = "consent-test@example.com";
const phone = "+40700000000";
const sha256 = (value: string) =>
createHash("sha256").update(value).digest("hex");
const secrets = [email, phone, sha256(email), sha256(phone)];
test("no contact details leave the page before consent", async ({ page }) => {
const leaks: string[] = [];
page.on("request", (request) => {
const url = request.url();
if (!TRACKER_DOMAINS.some((domain) => url.includes(domain))) return;
const sent = url + (request.postData() ?? "");
if (secrets.some((secret) => sent.includes(secret))) leaks.push(url);
});
await page.goto("/contact"); // fresh profile: nothing accepted
await page.getByLabel("Email").fill(email);
await page.getByLabel("Phone").fill(phone);
await page.getByRole("button", { name: "Send" }).click();
expect(leaks).toEqual([]);
const cookies = await page.context().cookies();
const tracking = cookies.filter((c) => TRACKING_COOKIES.includes(c.name));
expect(tracking).toEqual([]);
});
Ce pune în pericol
Date personale trimise la terți fără consimțământ, adică expunere pe GDPR și ePrivacy pentru platformă. Faptul că datele sunt hash-uite nu schimbă nimic.
