Skip to content

fix(security): redact email PII from auth-flow logs (#4254)#4255

Merged
realmeylisdev merged 5 commits into
mainfrom
fix/4254-redact-email-from-auth-logs
May 11, 2026
Merged

fix(security): redact email PII from auth-flow logs (#4254)#4255
realmeylisdev merged 5 commits into
mainfrom
fix/4254-redact-email-from-auth-logs

Conversation

@realmeylisdev
Copy link
Copy Markdown
Contributor

@realmeylisdev realmeylisdev commented May 11, 2026

Description

Systematic redaction of email PII from auth-flow logs. Flagged in #3784's review (point 4) but kept out of the emergency-security scope of that PR; this PR is the dedicated follow-up.

Audit of origin/main found 7 sites that log email at info/warning level across PendingVerificationService, DivineAuthCubit, EmailVerificationCubit, and EmailVerificationScreen. Redacting only the one line Rabble flagged would create inconsistency without security benefit; this PR addresses all 7 sites via a single helper plus a broadened Crashlytics sanitizer.

Related Issue: Closes #4254

What's in this PR

File Change
mobile/lib/utils/sensitive_uri_for_logs.dart New redactEmailForLogs(String) helper (Option B — partial-redact, preserves domain)
mobile/lib/observability/reportable_error.dart Broaden sanitizeForCrashReport to strip emails alongside npub/nsec
mobile/lib/services/pending_verification_service.dart Wrap 3 log call sites (save / expired / loaded)
mobile/lib/blocs/divine_auth/divine_auth_cubit.dart Wrap 2 log call sites (verification-required / password-reset)
mobile/lib/blocs/email_verification/email_verification_cubit.dart Wrap 1 log call site (startPolling)
mobile/lib/screens/auth/email_verification_screen.dart Wrap 1 log call site (persisted auto-login path)
mobile/test/unit/utils/sensitive_uri_for_logs_test.dart +9 cases for the new helper
mobile/test/observability/reportable_error_test.dart +4 cases for email stripping in the Crashlytics path
mobile/test/screens/auth/email_verification_screen_test.dart Regression test for persisted auto-login log redaction

Redaction strategy

Chose Option B — partial over Option A — opaque ([REDACTED]):

user@example.com   → u***@example.com
alice@gmail.com    → a***@gmail.com
first.last+tag@x.y → f***@x.y

Rationale: preserves the domain so ops can spot patterns like "all gmail.com users are failing" without identifying individual accounts. Local-part collapses to a fixed-width x*** mask regardless of length so original length isn't leaked.

Empty / malformed input (no @, empty local-part, domain without .) falls back to the existing redactedSensitiveLogPlaceholder ([REDACTED]).

Type of Change

  • 🛠️ Bug fix (non-breaking change which fixes an issue)

Coordination with #3784

#3784 (still open at time of writing) adds one overlapping auth-log site on top of the 7 handled here:

Whichever PR merges second will need a tiny rebase to wrap that site too. There is no functional dependency between the two PRs; they only overlap in the same service.

Test plan

  • flutter analyze lib test integration_test — no issues
  • flutter test test/unit/utils/sensitive_uri_for_logs_test.dart — 20/20 (9 new + 11 existing)
  • flutter test test/observability/reportable_error_test.dart — 17/17 (4 new + 13 existing)
  • flutter test test/blocs/divine_auth/ test/blocs/email_verification/ test/services/email_verification_listener_test.dart — 96/96 (regression on the originally wrapped auth-log sites)
  • flutter test test/screens/auth/email_verification_screen_test.dart — 16/16 (regression on the persisted auto-login log path)
  • Manual: verified the helper output for the documented shapes in unit tests

Follow-ups (not in this PR)

  • Optional CI guard mirroring grep_for_nsec_payload.sh to flag any new Log\.(info|debug|warning|error).*email patterns that bypass the helper.
  • Other PII (phone numbers, full names) in logs — out of scope for this issue; file separately if discovered.

Copy link
Copy Markdown
Contributor

@hm21 hm21 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

realmeylisdev and others added 2 commits May 11, 2026 12:25
Email addresses were logged in plaintext at 6 sites across the auth
flow (3 in PendingVerificationService, 2 in DivineAuthCubit, 1 in
EmailVerificationCubit). Flagged in #3784's review (point 4) but kept
out of the emergency-security scope of that PR — addressed here as
the systematic fix.

Approach:

- New `redactEmailForLogs(String)` helper in
  lib/utils/sensitive_uri_for_logs.dart. Partial-redaction
  (`user@example.com` → `u***@example.com`) preserves the domain so
  ops can correlate failure patterns per provider without identifying
  individual accounts. Empty / malformed input returns the existing
  `redactedSensitiveLogPlaceholder`.

- Broadened `sanitizeForCrashReport` in
  lib/observability/reportable_error.dart to also strip emails before
  forwarding to Crashlytics — defense-in-depth so any future call
  site that forgets the helper still gets sanitized when its error
  flows through `Reportable.toString()`.

- All 6 call sites on origin/main wrapped with the helper. The 7th
  site (the legacy-nsec migration warning added by #3784) is
  intentionally NOT included here — whichever of #3784 / this PR
  merges second receives a small rebase to wrap that site too.

Tests:
- 9 new cases for `redactEmailForLogs` (standard, single-char, long
  local-part, subdomains, empty, no-`@`, empty local-part, no-TLD
  domain, whitespace).
- 4 new cases for `sanitizeForCrashReport` covering email stripping,
  multiple emails, mixed npub/nsec/email, and domain preservation.

Closes #4254.
@NotThatKindOfDrLiz NotThatKindOfDrLiz force-pushed the fix/4254-redact-email-from-auth-logs branch from c580c3b to 87d53fa Compare May 11, 2026 17:25
Comment thread mobile/test/observability/reportable_error_test.dart
Comment thread mobile/lib/observability/reportable_error.dart
Copy link
Copy Markdown
Member

@NotThatKindOfDrLiz NotThatKindOfDrLiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shared email redaction path is in place, the alignment regression test is covering the cleanup, and checks are green on the current head.

@realmeylisdev
Copy link
Copy Markdown
Contributor Author

realmeylisdev commented May 11, 2026

Thanks @NotThatKindOfDrLiz and @hm21 — both review threads addressed and resolved. The Crashlytics path now routes through the shared redactEmailForLogs helper, and the test pins sanitizeForCrashReport to that helper rather than a literal mask, so future changes to either surface fail loudly instead of drifting silently.

@realmeylisdev realmeylisdev merged commit fad5239 into main May 11, 2026
10 checks passed
@realmeylisdev realmeylisdev deleted the fix/4254-redact-email-from-auth-logs branch May 11, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(security): redact email PII from auth-flow logs

3 participants