PII separated from identifiers; analytics uses pseudonymous IDs
Why it matters
Sending raw email addresses or full names to analytics platforms violates GDPR Art. 25 (data protection by design) and Art. 5(1)(b) (purpose limitation) because analytics processors are not authorized recipients of identifying PII under most privacy policies. OWASP A02 flags unnecessary PII exposure as a cryptographic and privacy failure. CWE-359 specifically covers unintended exposure of private information to third parties — which is exactly what happens when analytics.identify(user.email) fires. If a Segment, Mixpanel, or GA4 account is breached or subpoenaed, the attacker or regulator receives a map from behavioral data to real identities. ISO-27001:2022 A.5.34 requires privacy controls to be embedded in processing, not bolted on afterward.
Severity rationale
Critical because sending PII to third-party analytics processors creates an irrevocable exposure — once transmitted, you cannot undo the data transfer or control downstream retention.
Remediation
Replace direct PII in analytics calls with a salted SHA-256 hash. Add this to lib/analytics.ts and use it everywhere you call identify() or set user_id.
// lib/analytics.ts
import { createHash } from 'crypto'
// One-way, consistent pseudonymous ID per user
export function pseudoId(email: string): string {
return createHash('sha256')
.update(email + process.env.ANALYTICS_SALT!)
.digest('hex')
.slice(0, 16)
}
// Segment / Amplitude / Mixpanel:
analytics.identify(pseudoId(user.email), {
plan: user.plan, // OK — not PII
createdAt: user.createdAt
// Never: email, name, phone, address
})
// GA4:
gtag('config', 'G-XXXXXXXX', { user_id: pseudoId(user.email) })
Audit logs must reference userId (UUID), not email or name. Keep PII-to-ID correlation in a secure internal admin tool only, never in the log store itself.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Data Protection Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-359 — Exposure of Private Personal Information to an Unauthorized Actor
- owasp:2021 · A02 — Cryptographic Failures
- gdpr · Art. 25 — Data protection by design and by default
- iso-27001:2022 · A.5.34 — Privacy and protection of PII
Taxons
History
- 2026-04-18·v1.0.0·Initial import from data-protection·automated