Jul 24, 2026·6 min read·3 visits
Unicode homoglyphs of the '@' symbol bypass structural email validation in NextAuth.js and are normalized downstream, enabling passwordless account takeovers.
A security vulnerability in the email normalization logic of NextAuth.js and Auth.js allows remote attackers to bypass email validation constraints and achieve Account Takeover (ATO) through Unicode homoglyph smuggling. Under standard conditions, Unicode compatibility characters represent visually similar symbols that are normalized downstream to ASCII equivalents, facilitating structural validation bypasses. This issue specifically affects passwordless email authentication flows.
Auth.js and NextAuth.js are highly adopted open-source authentication frameworks designed to secure Next.js and React applications. Among their core features is the passwordless Email Provider, which allows users to authenticate by entering their email address and receiving a temporary, cryptographically secured 'magic link'. This design simplifies user onboarding and eliminates the security risks associated with storing and validating traditional user passwords.\n\nThe attack surface for this system resides within the email input normalization and parsing routines. Before generating and dispatching a sign-in token, the application must perform structural and syntactic checks on the user-supplied string to prevent standard vector injections, address parser confusion, and mail routing exploits. Ensuring that the address conforms to strict RFC specifications is a critical first-line defense in passwordless architectures.\n\nThe vulnerability is classified under CWE-180 (Validate Before Canonicalize) and CWE-20 (Improper Input Validation). In the affected versions, the framework executes format validation checks on the raw email string prior to performing Unicode canonicalization. Consequently, structural validation bypasses can be achieved by utilizing specific Unicode homoglyphs that later decompose into standard ASCII delimiters during downstream email routing.
The technical root cause is a fundamental sequence error in the input processing pipeline, specifically characterized as a 'validate-before-canonicalize' flaw. The default normalizer is tasked with verifying that an email address contains exactly one commercial at (@) symbol (U+0040) to segregate the local part from the domain part. This validation is designed to block malicious multi-recipient formatting and address manipulation.\n\nUnicode compatibility decomposition (NFKC) maps distinct characters to equivalent forms for consistent processing. Within the Unicode character set, several homoglyphs visually replicate the standard ASCII '@' symbol but possess unique code points. Most notably, the characters U+FF20 (FULLWIDTH COMMERCIAL AT: @) and U+FE6B (SMALL COMMERCIAL AT: ﹫) are handled as unique characters by the pre-canonicalization validation routine.\n\nBecause the validator specifically searched for the standard ASCII '@' byte (U+0040), the presence of U+FF20 or U+FE6B bypassed the check for duplicate routing separators. The normalizer treated the input string as having only a single ASCII '@' symbol, allowing the authentication request to proceed. Downstream components, such as nodemailer or local SMTP servers, then applied Unicode NFKC normalization, automatically converting the homoglyphs to standard '@' signs and producing a dual-delimiter address structure.
An examination of the vulnerable code in the NextAuth.js core reveals that the normalizer extracted and verified the local and domain segments using the raw, trimmed string. This sequence allowed Unicode characters to bypass structural checks before they were converted to their ASCII equivalents.\n\ntypescript\n// Vulnerable Implementation in packages/next-auth/src/core/routes/signin.ts\nconst normalizer = provider.normalizeIdentifier ?? ((identifier) => {\n const trimmedEmail = identifier.trim()\n // Validation checks occur here on the raw trimmedEmail\n // An input of 'attacker@evil.com@victim.company.com' is allowed\n})\n\n\nThe remediated implementation resolves this sequence error by enforcing Unicode NFKC normalization as the absolute first action in the input-handling pipeline. By calling identifier.normalize('NFKC') before performing any trim or validation actions, any embedded Unicode homoglyphs are immediately resolved to standard ASCII '@' characters, where they are correctly caught and rejected by the single-at validation routine.\n\ntypescript\n// Remediated Implementation with Front-loaded Canonicalization\nconst normalizer = provider.normalizeIdentifier ?? ((identifier) => {\n // Normalize homoglyphs prior to validating the string structure\n const trimmedEmail = identifier.normalize(\"NFKC\").trim()\n // Validation checks now encounter multiple standard '@' characters and throw an error\n})\n
Exploitation of this vulnerability requires no authenticated access and can be executed remotely. The target must be an application using the passwordless Email Provider on an affected version of NextAuth.js or Auth.js. The objective is to hijack the verification token generated during the sign-in flow and achieve unauthorized access to a victim domain.\n\nThe attacker crafts an authentication payload structured to exploit the downstream parser. A standard payload is attacker@evil.com@victim.company.com, where @ represents the fullwidth '@' homoglyph. When submitted to the sign-in route, NextAuth.js detects only one standard '@' character (the one separating 'attacker' and 'evil.com') and passes the input as a syntactically valid email for the domain victim.company.com.\n\nThe application generates a verification token and invokes the configured email provider to dispatch the magic link. During the dispatch process, the email delivery engine applies NFKC normalization, converting the string to attacker@evil.com@victim.company.com. Depending on the parsing engine of the MTA, the email is either routed to both addresses or delivered directly to the attacker-controlled server at evil.com. The attacker retrieves the token and authenticates as the victim.
The security impact of this vulnerability is severe, potentially resulting in full Account Takeover (ATO) and unauthorized privilege escalation. In passwordless systems, the magic link serves as the primary credential; gaining access to this link is functionally equivalent to compromising a user password. Attackers can targetedly compromise administrative or high-value corporate accounts simply by targeting their respective domains.\n\nThe vulnerability maps to several critical tactics in the MITRE ATT&CK framework. By bypassing input validation to hijack authenticated sessions, this flaw enables Initial Access via Valid Accounts (T1078), Credential Access through Modify Authentication Process (T1556), and Privilege Escalation via Abuse Elevation Control Mechanism (T1548).\n\nBecause this vulnerability has no assigned CVE and is tracked solely under the GitHub Advisory ID GHSA-7RQJ-J65F-68WH, standard vulnerability scanners and security dashboards that pull information exclusively from the NVD will not alert on its presence. This creates a hidden operational risk where legacy systems remain vulnerable indefinitely due to a lack of scanning visibility.
Remediation requires upgrading the authentication library to a patched release. For NextAuth.js v4, developers must update next-auth to version 4.24.15 or higher. For NextAuth.js v5 beta, the dependency must be updated to version 5.0.0-beta.32 or higher. If using @auth/core directly, update the package to 0.41.3 or higher.\n\nmermaid\ngraph LR\n Input[\"Email Input\"] --> Norm[\"NFKC Normalization\"]\n Norm --> Val[\"Single '@' Check\"]\n Val --> Route[\"Safe SMTP Routing\"]\n\n\nIf upgrading immediately is not feasible, a temporary workaround can be achieved by overriding the default normalizer callback. Developers must configure the normalizeIdentifier option within their Email Provider configuration to explicitly normalize inputs before validation. Any custom parsing scripts should similarly implement String.prototype.normalize('NFKC') as their first step.\n\nTo detect ongoing exploitation attempts, security operations teams should implement WAF rules to inspect POST requests to authentication routes (e.g., /api/auth/signin/email). Payloads containing Unicode homoglyphs, specifically \\uFF20 or \\uFE6B, should be flagged and blocked immediately. Log analysis should also scan database records for legacy normalized addresses containing multiple '@' characters.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
next-auth NextAuth.js | < 4.24.15 | 4.24.15 |
next-auth NextAuth.js | 5.0.0-beta.0 to < 5.0.0-beta.32 | 5.0.0-beta.32 |
@auth/core Auth.js | < 0.41.3 | 0.41.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-180 (Validate Before Canonicalize) |
| Attack Vector | Network (Remote, Unauthenticated) |
| CVSS v3.1 Score | 8.1 (High) |
| Exploit Status | Proof-of-Concept (PoC) Verified |
| CISA KEV Status | Not Listed |
| Impact | Account Takeover (ATO) |
The application validates input before it is canonicalized, enabling bypasses when different representations resolve to the same canonical form.
A critical logical security flaw exists in Auth.js (formerly NextAuth.js) where signed anti-CSRF check cookies (state, nonce, and PKCE code_verifier) are not bound to the specific Identity Provider that initiated the authorization flow. In multi-provider environments, this allows an attacker to replay valid, cryptographically signed cookies minted during a flow with one provider against a callback handling a different provider. This vulnerability can lead to session hijacking, identity theft, or unauthorized account linking.
Auth.js (formerly NextAuth.js) contains a denial of service vulnerability due to an uncaught URIError in the getToken() token parser when processing malformed percent-encoded sequences in bearer tokens. Additionally, the library was vulnerable to session state confusion and replay attacks because OAuth check cookies (state, nonce, and PKCE) were not properly bound to specific providers, permitting cross-provider token reuse.
CVE-2026-53467 is a heap information disclosure vulnerability in the Multiple-image Network Graphics (MNG) decoder of ImageMagick. The vulnerability arises from a failure to zero-initialize newly allocated pixel cache memory buffers. A remote attacker can exploit this by submitting a crafted sparse MNG image file to trigger uninitialized memory preservation. The resulting output contains residual heap bytes, potentially leaking sensitive process memory or assisting in ASLR bypass.
An untrusted deserialization vulnerability exists in the c3p0 JDBC connection pooling library before version 0.14.0. Standard JDBC getter methods conform to the JavaBean property getter pattern, allowing introspection libraries like Apache Commons BeanUtils to evaluate connection properties dynamically during deserialization, leading to arbitrary code execution when chained with a vulnerable database driver or JNDI sink.
A heap-based buffer overflow vulnerability exists in the native C extension of the Ruby json gem (versions 2.9.0 through 2.19.8) during IO-based streaming serialization. An incorrect buffer size calculation can lead to memory corruption and process termination when processing large strings.
An uncontrolled memory allocation vulnerability (CWE-789) exists in pypdf prior to version 6.14.0. The library blindly trusted user-controlled image dimensions (/Width and /Height) from PDF metadata, allowing attackers to trigger physical memory exhaustion and an Out-of-Memory crash via tiny, malformed files.