Passing email addresses or full names as analytics user identifiers or event properties violates GDPR Art. 5(1)(c) (data minimisation) and OWASP A02 (Cryptographic Failures / data exposure). Most analytics platforms (GA4, Mixpanel) explicitly prohibit PII in their terms of service and will terminate accounts that send it. Beyond compliance, PII in analytics creates a data breach vector: analytics dashboards are typically accessible to more people than your production database, and data export APIs make the PII recoverable by anyone with dashboard access.
Critical because PII in analytics events is both a GDPR Art. 5(1)(c) violation and a breach of analytics platform ToS — CWE-359 exposure that creates an additional data breach surface outside your production security controls.
Replace every analytics.identify(user.email, ...) call with an opaque database ID. Audit all identify(), posthog.identify(), and gtag('set', 'user_properties', ...) calls in lib/analytics.ts and any component that wraps them:
// Wrong — sends PII to analytics platform:
analytics.identify(user.email, { plan: user.plan })
// Correct — opaque ID only:
analytics.identify(user.id, { plan: user.plan })
If your analytics workflow requires looking users up by email, do that mapping inside your own database — never pass the email to the analytics SDK. Scrub any existing event schemas that include email, name, phone, or address as properties.
ID: marketing-analytics.privacy-compliance.no-pii-in-analytics
Severity: critical
What to look for: Analytics events must not include personally identifiable information. Scan analytics event calls for PII patterns:
email, userEmail, emailAddress, or @ in string concatenation near analytics calls)name, fullName, firstName, lastName) used as user IDs or event propertiesNote: Using an opaque database ID (UUID, numeric ID) as the analytics user ID is correct and not PII. The check is specifically for human-readable identifiers.
Pass criteria: Enumerate all analytics.identify(), posthog.identify(), mixpanel.identify(), and gtag('set', 'user_properties', ...) calls — at least 0 PII violations found across all calls. No analytics event calls include email addresses, full names, phone numbers, or other PII as event properties or user identifiers. Database IDs used as user identifiers are acceptable. Quote the actual identifier variable name used in each identify call.
Fail criteria: Any analytics event call includes what appears to be an email, full name, phone number, or other PII. OR analytics.identify() is called with the user's email as the user ID. Do not pass if the variable passed to identify is named email, userEmail, or contains @ in a hardcoded string.
Skip (N/A) when: No analytics is present. Skip if no analytics.identify() or user property calls exist (purely anonymous tracking).
Detail on fail: "analytics.identify() called with user.email as the user ID in lib/analytics.ts. Email addresses are PII — using them as analytics identifiers violates GDPR and most analytics platforms' terms of service."
Remediation: Never use email addresses as analytics user identifiers. Use an opaque database ID:
// Wrong:
analytics.identify(user.email, { plan: user.plan })
// Correct:
analytics.identify(user.id, { plan: user.plan })
If you need to look up users by email in your analytics tool, use the email as a trait (property) only — not as the primary identifier. Even then, consider whether this is necessary. For a broader review of PII handling in your application, the AI Data Privacy audit examines data exposure patterns across your entire codebase.