Urgent.News

What's breaking now, across thousands of outlets.

Tech

A full-width email address got past our signup checks. Normalize with NFKC, then insist on ASCII.

One of our verification emails bounced this week with an error we had never seen: 422 Invalid `to` field. The email address contains non-ASCII characters. The address looked normal at a glance. It was not. The domain had been typed in full-width characters, the forms you get from a CJK input method: example.tech instead of example.tech . Our signup form accepted it, our database stored it, and…

Our latest verification bounced an email with a peculiar error we hadn't encountered before: 422 Invalid `to` field. The address contained non-ASCII characters. To the untrained eye, the address appeared normal. The issue lay in the domain, which had been typed using full-width characters, such as example.tech instead of the correct example.tech.

Our signup form accepted the address, storing it in our database, and only the mail provider detected the discrepancy. This presents both a correctness and a consistency bug. Any aspect of our system that relies on the domain, such as rate limits, duplicate checks, or a blocklist, encountered a mismatching string. Various browsers handle this differently: Chrome's input type= email block prohibited the full-width address, but a script posting directly to the endpoint could submit it.

Client-side validation is a user experience feature, while the server must still determine what constitutes a valid email address. The solution involved normalizing the email address before any other processing. By using Unicode NFKC normalization, compatibility characters are mapped to their plain forms, converting full-width letters, the full-width "@" symbol, and the full-width "." into their ASCII equivalents.

To implement this fix, normalize the email address once, at the boundary, before any other component validates it. This ensures that rate limits, duplicate checks, and the stored address all encounter the same string. If one code path normalizes the address and another does not, a bypass is created. Apply normalization to every method of account creation.

We have both email signup and Google sign-in; both routes pass through the same normalization function. Even if an OAuth provider hands over an email string, it remains input requiring normalization. While we accepted email addresses like user@bücher.de as real, valid internationalized addresses, we now reject them. Our mail provider cannot deliver emails with non-ASCII addresses, so accepting them only resulted in unverifiable accounts.

If your provider supports SMTPUTF8, you could retain the NFKC normalization and either drop the ASCII check or convert the domain to punycode instead. Testing confirmed that full-width input is stored as its ASCII form, and a verification email sent to the ASCII address would not create an account. A blocklisted domain remains blocked, regardless of whether it was typed in full-width or plain ASCII.

ASCII addresses continue to function as before. With just ten tests, one function, and a class that treats the same address as identical regardless of its byte representation, we resolved the issue of "same address, different bytes."

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Security Audit Report: Reentrancy & Access Control Review: Rocket Pool

Security Audit Report: Reentrancy & Access Control Review: Rocket Pool Target Protocol : Rocket Pool (TVL: $1277.3M) Security Audit Report – Reentrancy & Access‑Control Review Protocol: Rocket Pool…

  • Rocket Pool protocol audit reveals three reentrancy vulnerabilities in core contracts
  • Overall risk score classified as High due to exploitable admin functions and supply inflation risks

More from Thursday 22 October →