Skip to main content
ESLint Interlace
Plugin: browser-securityRules

no-sensitive-data-in-analytics

This rule detects when sensitive user data (email, SSN, credit card, password, phone, address) is passed to analytics...

Prevents PII being sent to analytics services

Severity: 🟠 HIGH
CWE: CWE-359: Exposure of Private Personal Information to an Unauthorized Actor
OWASP Mobile: M6: Inadequate Privacy Controls

Rule Details

This rule detects when sensitive user data (email, SSN, credit card, password, phone, address) is passed to analytics tracking calls like analytics.track(). Analytics platforms may not provide adequate security for sensitive data, and data breaches in analytics services can expose user PII.

Why This Matters

Analytics platforms are third-party services with their own security postures. Sending PII to analytics:

  • Violates GDPR Article 6 (lawful processing)
  • Creates regulatory compliance risks (GDPR fines up to €20M or 4% of revenue)
  • Exposes data to third-party breaches (analytics provider compromises)
  • May violate user privacy expectations and consent agreements

❌ Incorrect

// Sending email to analytics
analytics.track('User Signup', {
  email: user.email, // ❌ PII in analytics
  userId: user.id,
});

// Sending credit card details
analytics.track('Payment', {
  creditCard: cardNumber, // ❌ PCI-DSS violation
  amount: total,
});

// Sending password (never!)
analytics.track('Login Attempt', {
  username: user.username,
  password: user.password, // ❌ Critical security violation
});

// Sending SSN
analytics.track('Profile Update', {
  ssn: user.ssn, // ❌ HIPAA/PII violation
  name: user.name,
});

✅ Correct

analytics.track('page_view', { page: '/home' })

⚙️ Configuration

This rule has no configuration options.

Known False Negatives

The following patterns are not detected due to static analysis limitations:

PII from Variables or Function Returns

Why: We only analyze object literal properties passed directly to analytics.track(). Values from variables or function calls are not traced.

// ❌ NOT DETECTED - PII from variable
const userData = { email: user.email, phone: user.phone };
analytics.track('Event', userData);

Mitigation: Always review analytics tracking code manually for PII. Use TypeScript branded types to mark PII data.

Custom Analytics Wrappers

Why: We only detect analytics.track() calls. Custom wrapper functions are not recognized.

// ❌ NOT DETECTED - Custom wrapper
function trackUserEvent(data: any) {
  analytics.track('Event', data);
}
trackUserEvent({ email: user.email }); // PII in custom wrapper

Mitigation: Apply this rule to wrapper function implementations. Document analytics wrappers in code review guidelines.

Dynamic Property Names

Why: Properties accessed via bracket notation or computed property names cannot be statically analyzed.

// ❌ NOT DETECTED - Dynamic property
const field = 'email';
analytics.track('Event', {
  [field]: user[field], // Dynamic, can't determine if PII
});

Mitigation: Avoid dynamic property names for analytics tracking. Use explicit, static property names.

📚 References