A homograph attack exploits ambiguity between strings that appear similar to a human but differ as identifiers. Unicode expands the possible writing systems and glyph shapes, yet not every use of multiple scripts is suspicious. A defensible threat model focuses on who is making a trust decision, which origin or account is protected and where the interface might obscure the actual identifier.
Define the attacker-controlled surface and the decision
The relevant surface might be a display name, package name, URL label, commit author field or selected account in a payment workflow. The threat is not the existence of Cyrillic or Greek text: it is a consumer mistaking an untrusted identifier for a specific trusted one.
The same lookalike has different impact in a poetry corpus and a password-reset interface. Begin an assessment by listing trusted labels, entry points and downstream actions. Protect especially the surfaces where a display label alone determines the selected account or network origin.
A visual match does not imply a code-point match
Latin a U+0061 and Cyrillic а U+0430 are separate characters. A string comparator can easily distinguish them, but users may not when a UI uses a small font or a truncated label. Fonts and antialiasing affect how closely they resemble each other.
An interface should not hide origin context in an image-only badge or truncated filename. Defensive inspection can show the normalized comparison result, original scalar values and the full credential-relevant target. This does not require rewriting multilingual content.
Cross-script confusability is only one route
UTS #39 includes single-script, mixed-script and whole-script confusables. A visually ambiguous pair need not mix scripts inside one candidate: strings from different single scripts can resemble each other, and even one script can contain near-lookalikes.
Therefore a detector limited to 'does this word contain Cyrillic and Latin?' will miss threats. Conversely, it will falsely label legitimate bilingual strings. Incorporate protected-name comparisons and clear policy rather than using a raw mixed-script boolean as proof of fraud.
Internationalized hostnames add separate IDNA processing
Internationalized Domain Names for Applications (IDNA) maps valid Unicode labels to DNS-compatible ASCII labels, often using an xn-- A-label form based on Punycode. This conversion is about interoperable DNS labels, not deciding whether a human can be fooled by a confusable.
Browsers may choose to show an IDN as Unicode or as an A-label according to product-specific safety heuristics. Neither display choice alone proves trustworthiness. For a high-stakes origin confirmation, inspect the canonical origin and certificate or account context using native browser controls, not screenshots or embedded page text.
UTS #46 and IDNA2008 do not solve all spoofing
UTS #46 provides compatibility processing for internationalized domain names, while IDNA2008 specifies validity and processing constraints. Both allow legitimate non-ASCII writing systems. UTS #46 explicitly does not eliminate the general confusable problem.
One domain can be a valid IDN and still visually resemble another name. Security design needs a second layer: UTS #39-inspired identifier checks, domain-label policies, registrant protection and recognizable navigation surfaces.
Bidirectional controls can deceive outside URL labels
Bidi formatting controls may reorder displayed segments of filenames or source text while leaving their logical order unchanged. This can confuse users who judge a file extension or a code fragment only by its painted position. That is a display-layer risk distinct from same-shaped character substitution.
Expose directional control characters in security-sensitive inspectors. Render untrusted fragments in isolated containers and show explicit extensions, MIME types or file signatures where needed. Do not reverse text storage to make a screenshot appear left-to-right.
Defensive UI should minimize ambiguous authority cues
Show verified account identifiers, the relevant domain origin or an independently authenticated business identity alongside untrusted display names. Use explicit link destinations in review interfaces and avoid claiming a user's chosen Unicode nickname is a verified legal name.
Security labels and icons should have accessible alternatives. A screen reader may expose useful character naming differences, but its behavior varies across languages and platforms, so accessible naming cannot replace deterministic underlying origin checks.
User reporting and collision review need evidence
When users report a lookalike, collect the exact text, code-point sequence, intended protected identifier, URLs or account IDs, timestamps and screenshots. Avoid retaining unnecessary personal data, but store enough to reproduce the issue.
A screenshot alone can lose bidi controls and selector information. A confusable skeleton match is a useful automated finding, but human or policy review should decide whether enforcement is justified. Log Unicode security data version for reproducibility.
Test safe cases and legitimate exceptions together
Build a lab corpus representing trusted identifiers, intentionally ambiguous but non-operational examples and ordinary bilingual names. Assert that the system distinguishes exact matches, potential confusables and allowed mixed-script prose.
Measure false positives as well as detection. A globally enforced ASCII-only rule would remove most Unicode spoofing possibilities by excluding many legitimate users; that tradeoff is rarely appropriate outside deliberately constrained technical identifiers.
Reproducible technical example
Use the following minimal experiment to inspect representation rather than guessing from appearance. It does not implement a complete Unicode security algorithm, determine malicious intent, or measure platform-wide font support. Each of those tasks requires its own documented conformance or decision model.
const labelA = 'a';
const labelB = '\u0430';
const hex=s=>[...s].map(c=>'U+'+c.codePointAt(0).toString(16).toUpperCase());
console.log(hex(labelA),hex(labelB),labelA===labelB);
// Defensive example: retain exact source, compare against protected labels
// using a maintained UTS #39 implementation, and review possible collisions.
// Neither screenshot similarity nor an xn-- A-label alone confirms trust.Record the input Unicode scalars, the expected application behavior, and which layer first diverges: transport, parsing, normalization, security classification, layout, or accessibility. Use specific tool versions and preserve the original input for comparison after any policy decision.
Evidence matrix: distinguish text, appearance and policy
| Feature | Controlled input | Meaning |
|---|---|---|
| Source label | exact Unicode scalar sequence | identity differs from painted appearance |
| Confusable collision | UTS #39 skeleton | potential risk requiring context |
| IDN DNS form | A-label / U-label | DNS interoperability, not proof of legitimacy |
| Bidi control | U+202E or isolates | can change visual order without changing storage |
| Trusted origin | browser-confirmed origin | must not come from untrusted page text |
A similar-looking output is not proof of identical text. Equally, two strings with different scalar sequences may be intentionally equivalent under a narrowly defined product matching policy. When evaluating risk, separate exact identity, confusable matching, account verification and readable display.
Validation checklist and failure classification
- Source label. Build a reproducible specimen for
exact Unicode scalar sequenceand separately capture source scalars, normalization choices, policy settings and rendered output. The interpretation is: identity differs from painted appearance. Do not conflate a visual similarity with a binary equality or a security verdict. - Confusable collision. Build a reproducible specimen for
UTS #39 skeletonand separately capture source scalars, normalization choices, policy settings and rendered output. The interpretation is: potential risk requiring context. Do not conflate a visual similarity with a binary equality or a security verdict. - IDN DNS form. Build a reproducible specimen for
A-label / U-labeland separately capture source scalars, normalization choices, policy settings and rendered output. The interpretation is: DNS interoperability, not proof of legitimacy. Do not conflate a visual similarity with a binary equality or a security verdict. - Bidi control. Build a reproducible specimen for
U+202E or isolatesand separately capture source scalars, normalization choices, policy settings and rendered output. The interpretation is: can change visual order without changing storage. Do not conflate a visual similarity with a binary equality or a security verdict. - Trusted origin. Build a reproducible specimen for
browser-confirmed originand separately capture source scalars, normalization choices, policy settings and rendered output. The interpretation is: must not come from untrusted page text. Do not conflate a visual similarity with a binary equality or a security verdict.
Keep fixtures with positive cases, false positives and context-dependent exceptions. When an implementation returns a finding, show which Unicode characters and rules contributed to it. Avoid silently rewriting untrusted identifiers, and do not apply machine-identifier restrictions globally to multilingual prose.
Boundaries of automated conclusions
Standards offer useful algorithms and properties, not perfect attribution of a user's intent. Visual confusability, supported script combinations, locale, account reputation and actual network origin need independent evidence. A system should fail safely in high-trust contexts while preserving valid Unicode for normal communication.
Primary specifications and data sources
The references provide normative definitions and authoritative technical data where available. UTS #39 and UTS #46 are separate technical standards; conformance to the core Unicode Standard alone does not imply conformance to either. Product-specific warnings and enforcement thresholds remain implementation decisions.
- UTS #39 Unicode Security Mechanisms — primary standard or data source. Check the exact release version and the scope of its conformance claims; implementation policy and user-interface warnings are separate choices.
- UTS #46 IDNA Compatibility Processing — primary standard or data source. Check the exact release version and the scope of its conformance claims; implementation policy and user-interface warnings are separate choices.
- RFC 5890 IDNA Definitions — primary standard or data source. Check the exact release version and the scope of its conformance claims; implementation policy and user-interface warnings are separate choices.
- RFC 5891 IDNA Protocol — primary standard or data source. Check the exact release version and the scope of its conformance claims; implementation policy and user-interface warnings are separate choices.
- Unicode Bidirectional Algorithm UAX #9 — primary standard or data source. Check the exact release version and the scope of its conformance claims; implementation policy and user-interface warnings are separate choices.
Related published research
This article belongs to the Identifiers, Confusables & Security virtual silo. Nearby reference articles explain the adjacent Unicode, rendering and text-processing issues in greater depth.
- unicode confusables lookalikes
- mixed script text processing
- unicode bidirectional algorithm
- invisible characters text editors
Technical information is presented for defensive review, reproducible diagnostics and trustworthy text interchange. The original encoded content should remain available when any derived display or comparison representation is generated.