
An accent-insensitive email comparison lets an attacker-owned look-alike domain authenticate as the victim and quietly receive their password-reset link. No clicks. No phishing. Full takeover.
What We Found
During testing on a recent bug bounty engagement, we found that the application resolves and authenticates accounts using an accent-insensitive (diacritic-folding) email comparison. Accented Latin characters are treated as identical to their base ASCII letter during account lookup and password verification — ó (U+00F3) folds to o, é (U+00E9) folds to e.
The consequence is severe: an email on a completely different, attacker-owned domain collides with the victim’s account. redacted@wearehackeróne.com (note the ó in the domain) authenticates against the legitimate account redacted@wearehackerone.com. Chained with the password-recovery flow, this becomes a zero-click account takeover — the attacker receives a valid reset link for the victim’s account with no victim interaction whatsoever.
The Collision:
redacted@wearehackeróne.com → folds to → redacted@wearehackerone.com

Fig.1 The collision mechanism. Two addresses on different domains fold to the same canonical string, so the auth layer treats them as one account.
From Collision to Zero-Click Takeover
The auth-layer collision is interesting on its own. Chained with password recovery, it becomes catastrophic — because the reset message is generated against the attacker-submitted homoglyph address.

Fig: Attack path. The reset link is delivered to the attacker’s homoglyph mailbox the victim never sees or does anything.
01 · Confirm accent-insensitive matching. Send the homoglyph variant to the sign-in endpoint with the victim’s password and observe it resolve to the victim account — identical behaviour to the genuine address.
02 · Register the look-alike IDN domain. Purchase wearehackeróne.com (ó = U+00F3) — an inexpensive one-time cost — and configure a mailbox to receive mail for redacted@wearehackeróne.com.
03 · Trigger a password reset for the homoglyph address. POST the homoglyph address to /password-recovery-email. The app folds it to the victim account and issues a valid reset token but generates the message against the submitted address.

04 · Receive the victim’s reset link (zero-click). The reset email lands in the attacker-controlled homoglyph mailbox. No phishing, no malware, no victim interaction — the link simply arrives.

05 · Reset, log in, and own the account. Verify the recovery token, set a new password, and sign in. The reset re-establishes credentials, neutralising the victim’s existing two-factor protection in the process.

Why This Happened
Two design decisions combined to create the vulnerability. First, the email field is compared using an accent-insensitive collation, so visually distinct Unicode characters are treated as equal. Second and this is what turns a curiosity into a takeover — the password-reset message is generated for the user-submitted address rather than the account’s stored canonical address. The lookup folds one way (attacker input → victim account), but delivery uses the raw input, so the link goes to the attacker.

How to Fix It
- Canonicalise emails identically on registration and every lookup/recovery. Lowercase, apply Unicode NFC normalization, convert the domain to its A-label (punycode) form, and reject or strictly restrict non-ASCII characters. Store and compare only this canonical value.
- Use an accent-sensitive, binary-safe comparison. Switch the email column to a utf8mb4_bin collation or do an exact byte/string comparison in code, so visually similar but distinct characters are never treated as equal.
- Deliver reset and confirmation mail only to the stored canonical address. Never send to the user-supplied address from the request, and bind the reset token strictly to the resolved account.
- Treat homoglyph/IDN variants of an existing domain as a non-match. Block registration and recovery for confusable domains, and consider notifying users when a reset is attempted on their account.
The Bigger Picture
Unicode confusables are an old problem that keeps resurfacing in new places — usually wherever a system tries to be “helpful” by treating similar-looking strings as equal. For display, fuzzy matching is fine. For identity, it’s a security boundary, and equality must be exact.
The most dangerous part here wasn’t the collation alone — it was sending a security-sensitive message to unvalidated user input. Anywhere you resolve an identifier one way but act on the raw input another way, you’ve likely created a confused-deputy bug.
Canonicalise once, compare exactly, and only ever send secrets to the address you stored — never the one the request handed you.
