Skip to content

fix(server): block free-email provider domains from brand claims, unify parallel lists#4166

Merged
bokelley merged 2 commits intomainfrom
claude/issue-4165-free-email-brand-claim-guard
May 6, 2026
Merged

fix(server): block free-email provider domains from brand claims, unify parallel lists#4166
bokelley merged 2 commits intomainfrom
claude/issue-4165-free-email-brand-claim-guard

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

@bokelley bokelley commented May 6, 2026

Closes #4165

Summary

Extends SHARED_PLATFORM_DOMAINS in identifier-normalization.ts with 31 high-volume free-email provider domains (Gmail, Outlook, iCloud, Proton, Yahoo, AOL, Yandex, QQ, Tutanota, and others) as defense-in-depth against brand identity hijacking. WorkOS DNS verification makes admin-override exploitation implausible today, but the new primary_brand_domain auto-populate path added in #4157 and the markBrandDomainVerified webhook are both gated by assertClaimableBrandDomain — this closes the gap for admin overrides and future trust paths.

Extracts the list into an exported FREE_EMAIL_PROVIDER_DOMAINS constant and replaces five previously-diverged inline arrays across admin-tools.ts (check_domain_health + suggest_prospects), slack-db.ts, and admin/domains.ts (×2) with imports of the shared constant. The suggest_prospects handler was also using NOT LIKE '%@domain' patterns rather than parameterized NOT IN — migrated for consistency and completeness.

Adds assertClaimableBrandDomain unit tests; the function was previously untested despite being a security gate.

Non-breaking justification: Purely additive to a blocklist. Any domain entering SHARED_PLATFORM_DOMAINS that a legitimate brand already holds would have been blocked from claiming via WorkOS DNS verification anyway. Existing approved brand-claims are unaffected — assertClaimableBrandDomain gates new challenge issuance, not existing verified records. Server-only; no schema or protocol impact. Changeset is --empty.

Follow-up (out of scope for this PR): The security review noted that organizations.email_domain writes in the WorkOS webhook and admin/domains.ts are not guarded by assertClaimableBrandDomain. This is a separate blast radius (org membership auto-inference, not brand identity claim). Tracked for a follow-on issue.

Pre-PR review

  • security-reviewer (1st pass): approved approach — flagged parallel lists in slack-db.ts, admin/domains.ts, and suggest_prospects LIKE clause as blockers; all three resolved in this diff. Noted organizations.email_domain write path as a separate follow-up.
  • code-reviewer (1st pass): flagged parallel list drift (resolved) and missing assertClaimableBrandDomain tests (resolved). Confirmed me.com inclusion is correct (Apple-owned, no legitimate brand claimant).
  • code-reviewer (2nd pass): approved — spread into Set constructor is correct (no bypass via type widening), SQL parameterization shifts correctly at 31 items, no remaining blockers.

Triage-managed PR. This bot does not currently iterate on
review comments or PR conversation threads (only on the source
issue). To unblock:

  • Push fixup commits directly: gh pr checkout <num>
    fix → push.
  • Or re-trigger: comment /triage execute on the source
    issue.

See #3121
for context.

Session: https://claude.ai/code/session_01Wgjm3A6JbHWgfPCyDxUmoL


Generated by Claude Code

…fy parallel lists

Extends SHARED_PLATFORM_DOMAINS with 31 high-volume free-email provider
domains (Gmail, Outlook, iCloud, Proton, Yahoo, AOL, Yandex, QQ, Tutanota,
etc.) as defense-in-depth for brand identity hijacking via admin overrides
or future trust paths. Surfaced during security review of PR #4157.

Extracts FREE_EMAIL_PROVIDER_DOMAINS as a shared exported constant and
replaces five previously-diverged inline arrays across admin-tools.ts
(check_domain_health + suggest_prospects), slack-db.ts, and admin/domains.ts
(x2) with imports of the shared constant.

Adds assertClaimableBrandDomain unit tests (the function was previously
untested).

Closes #4165.

https://claude.ai/code/session_01Wgjm3A6JbHWgfPCyDxUmoL
@bokelley bokelley added the claude-triaged Issue has been triaged by the Claude Code triage routine. Remove to re-triage. label May 6, 2026
@bokelley bokelley marked this pull request as ready for review May 6, 2026 19:23
@bokelley bokelley merged commit 77bae0c into main May 6, 2026
15 checks passed
@bokelley bokelley deleted the claude/issue-4165-free-email-brand-claim-guard branch May 6, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude-triaged Issue has been triaged by the Claude Code triage routine. Remove to re-triage.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add free-email-provider domains to SHARED_PLATFORM_DOMAINS

2 participants