ANT-2026-7WJV60DR · supabase/auth
other medium
Severity Claude medium · Security research firm - · Maintainer -
Discovered by Claude Mythos Preview
Anthropic's analysis of this finding, sealed at approval.
ANT-2026-7WJV60DR: Manual identity linking enables account takeover via unverified email
When GOTRUE_SECURITY_MANUAL_LINKING_ENABLED is true, GET /user/identities/authorize calls linkIdentityToUser, which invokes createNewIdentity with whatever email the external provider returned without calling IsDuplicatedEmail or checking that the provider asserted the email as verified. Providers like Discord return a user's primary email even when unverified, so an attacker can link a Discord identity carrying victim@example.com to their own Supabase user. Later, when the real victim signs in via a default-linking-domain provider (e.g. Google), DetermineAccountLinking matches identities by email without filtering on verification and attaches the victim's new identity to the attacker's user. The attacker then controls the account the victim logs into.
Target
Project: supabase/auth
Location: internal/api/identity.go:135
Discovery: static analysis — not yet dynamically reproduced
Technical Details
linkIdentityToUser trusts the provider-returned email unconditionally: it neither checks IsDuplicatedEmail against existing users nor requires the provider to assert the email as verified. DetermineAccountLinking (linking.go:114) then queries identities by email alone, so an attacker-planted unverified-email identity is treated as a valid link target.
Reproduction
- Attacker creates a normal account on the target app.
- Attacker creates a Discord account and sets its email to victim@example.com without verifying it.
- While logged in, attacker calls GET /user/identities/authorize?provider=discord and completes OAuth; linkIdentityToUser writes an identity {provider:discord, email:victim@example.com, user_id:attacker}.
- Victim later signs in with Google using verified victim@example.com.
- DetermineAccountLinking matches the attacker's Discord identity by email and returns LinkAccount with User=attacker.
- Victim's Google identity is attached to the attacker's user; attacker can now log in as the victim.
[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]
Suggested Fix
Reject manual identity links whose email collides with another user, and restrict automatic account linking to identities whose email was asserted as verified by the upstream provider.
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-7WJV60DR.
Reference: ANT-2026-7WJV60DR
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure
Dates from discovery through public reveal.
- 2026-05-14 Reported to tracker
- 2026-05-14 Maintainer acknowledged
- 2026-05-15 Sent to maintainer
- 2026-08-05 Patch released
- 2026-08-18 Publicly revealed
SHA-3-512 hash:
c81a4fd0cd3fc7a9defc4f385a2675b0caa4db28ee228297557b9e09805c5cd4b746d33c15d7dba56a19f6b0af7da18f34f78636e5842b01f8135b380f0dccec
Committed 2026-05-17 18:02 PT
Revealed 2026-08-18 07:12 PT
Verify (download preimage.json)
Show preimage JSON
{
"ant_id": "ANT-2026-7WJV60DR",
"bug_class": "other",
"claude_severity": "medium",
"commit_sha": null,
"created_at": "2026-05-14T22:00:14+00:00",
"description": "When GOTRUE_SECURITY_MANUAL_LINKING_ENABLED is true, GET /user/identities/authorize calls linkIdentityToUser, which invokes createNewIdentity with whatever email the external provider returned without calling IsDuplicatedEmail or checking that the provider asserted the email as verified. Providers like Discord return a user's primary email even when unverified, so an attacker can link a Discord identity carrying victim@example.com to their own Supabase user. Later, when the real victim signs in via a default-linking-domain provider (e.g. Google), DetermineAccountLinking matches identities by email without filtering on verification and attaches the victim's new identity to the attacker's user. The attacker then controls the account the victim logs into.",
"discovered_at": "2026-05-10T00:00:00+00:00",
"location": "internal/api/identity.go:135",
"poc_sha256": null,
"preimage_version": 1,
"project": "supabase/auth",
"reproduction": [
"1. Attacker creates a normal account on the target app.",
"2. Attacker creates a Discord account and sets its email to victim@example.com without verifying it.",
"3. While logged in, attacker calls GET /user/identities/authorize?provider=discord and completes OAuth; linkIdentityToUser writes an identity {provider:discord, email:victim@example.com, user_id:attacker}.",
"4. Victim later signs in with Google using verified victim@example.com.",
"5. DetermineAccountLinking matches the attacker's Discord identity by email and returns LinkAccount with User=attacker.",
"6. Victim's Google identity is attached to the attacker's user; attacker can now log in as the victim."
],
"technical_details": "linkIdentityToUser trusts the provider-returned email unconditionally: it neither checks IsDuplicatedEmail against existing users nor requires the provider to assert the email as verified. DetermineAccountLinking (linking.go:114) then queries identities by email alone, so an attacker-planted unverified-email identity is treated as a valid link target.",
"title": "Manual identity linking enables account takeover via unverified email",
"vendor_severity": null
}