LookalikesLive · WhisperGraph
Whisper Labs. Field notes on the letters that lie

The web does not look the same to everyone.

Here is a domain. To half the planet it is your bank, your brand, the name you type without looking. To the other half it is junk. One copy. Registered to a stranger. Sitting on a threat feed while you read this.

the real one
a stranger’s copy

As Safari paints it, the forgery is pixel-identical to the real domain. One letter is wrong: a dotless ı standing where the i should be. At this size, in this font, you would not catch it.

registered to a stranger · on threat feeds · MEDIUM 3.6
right now you are seeing the web as San Francisco. Change browsers with the control below ↓
the evidence
here is a letter

Two letters. Two names in Unicode. The same pixels.

Unicode has tens of thousands of letters. Many of them are twins. Whether two twins actually land on the same spot is not up to Unicode. It is up to the font. Here are two of them, stacked, in Safari’s. Teal is the real letter. Red is the impostor. Bone is where the two become one, and that is where you stop being able to tell.

i · Latinı · dotless i · all the attacker had to do was drop the dot.

i · Latin
·
pixels shared
ı · dotless i
live check · whispergraph

Is your name a target?

Type a name. We swap one letter for a twin a real browser will paint convincingly, every way it can be done, and check each fake against 2.6B hostnames in WhisperGraph. What comes back is real. Registered right now. By someone who is not you. We also ask the registry who, and when.

try
the gap between browsers

The lie lives in the font, not the letter.

Rendered through the three font stacks browsers actually paint into the URL bar, 2,402 pairs of letters fold into one shape on some screen, somewhere. Only 400 of them fool all three. The rest depend on whose screen the domain lands on. The attack picks its victim by the font.

fool every browser
0%

of the 2,402 confusable pairs are indistinguishable in all three shipping fonts. A forgery that survives the trip to every device. The other 83% only work somewhere. And somewhere is wherever the victim happens to be.

browser-conditional
0%

of the registered look-alikes that fool any browser are browser-conditional . Flawless on one machine, plainly wrong on the next. The attack picks a font, and takes whoever is behind it.

where the 2,402 pairs land

Seven regions. One agreement.

Each browser keeps its own private stock of forgeries. Edge alone holds 788, Safari 229, Chrome 262 that no other font draws.

ChromeRoboto + Noto (OFL)SafariSan FranciscoEdgeSegoe UIfools all three

Hover, tap, or tab across the bars. Counts are confusable pairs; the filled dots mark which browsers merge them.

how a font lies

Two alphabets. One set of pixels.

Latin h (U+0068) and Armenian ho հ (U+0570) are unrelated letters. Lay the glyphs each browser actually draws on top of each other: Segoe UI puts them on the very same pixels, while Roboto + Noto (OFL) keeps them apart. Same domain, same codepoints. Whether you ever see the lie is decided by the machine you happen to own.

Segoe UI · Edge
Roboto + Noto · Chrome
ink both shareink where they differ
registered attacks · per browser
0%

of registered look-alikes that fool any browser are browser-conditional . Pixel-identical on some machines, plainly off on others.

171 of 313 fool at least one browser; only 142 of 529 fool all three.

ChromeRoboto + Noto (OFL)171/52932%
SafariSan Francisco284/52954%
EdgeSegoe UI304/52957%

Red bar = the share of 529rendered substitutions, drawn from real registered domains, that are indistinguishable in that browser’s URL-bar font; the pale notch is the 95% confidence interval. Chrome’s Roboto + Noto separate the most. Segoe UI merges the most.

we tried to make it go away

We re-ran the whole pipeline across a sweep of similarity cutoffs, and the share of pairs that fool all three browsers never left the 1518% band. So the disagreement between browsers is not a number we picked. It is in the fonts.

the other axis · the name in another language

A name can be forged by how it is written, not just by how it looks.

Every forgery so far leaned on a glyph that copies Latin. Here is the other move: write the name in another language, or hang it under a top-level domain that quietly means the same word somewhere else. Both resolve today. The variant engine’s fourteen algorithms see none of it.

a same-meaning TLD already taken
0%

of 562 major brands already have a registered domain on an IDN top-level domain that is com in another language . 公司, 닷컴, كوم. 249 live names in all.

the name, phonetically
0%

have a registered transliteration of their name in another script . аппле, μετα, 디올. 219 live names, across 12 scripts.

the conflated root zone

The map nobody draws.

ICANN treats every top-level domain as independent. But 93 of the 151 delegated internationalized TLDs are, in plain language, the same word in another script. Grouping into 61 cross-language equivalence classes. You can’t invent a TLD, so this is curation of what is already delegated; every equivalence here was recomputed to its xn-- form and checked against the live IANA root.

.com
集团group/conglomerate
公司company
企业enterprise
कॉमcom
קוםcom
كومcom
닷컴dot-com
transliteration · spelled “com”semantic · means “company”
.inone country · 10 scripts
ಭಾರತভাৰতভারতభారత్ભારતभारतبھارتഭാരതംਭਾਰਤஇந்தியா
.net
网络网址नेट닷넷
.store
商店商城بازار
.online
在线онлайн
.cn
中国中國
.ru
рф
label transliteration

One name. Every alphabet.

Spell the name by ear in another script and it still sounds like the brand, though not one letter is the same. You can register it under any TLD. Put both moves together and you get a spoof, fully translated: гоогле.рф, google.公司.

google
гоогле
Cyrillicrt 1.00
γοογλε
Greekrt 1.00
גֳֳגלֶ
Hebrewrt 1.00
գոոգլե
Armenianrt 1.00
გოოგლე
Georgianrt 1.00
고옥레
Hangulrt 1.00
गॊऒग्लॆ
Devanagarirt 0.86
ゴオグレ
Katakanart 0.71

rt = round-trip faithfulness · spell it back into Latin and compare. 1.00 = the forgery reads as the brand.

already registered

Not a what-if. Live in the graph.

Made for 562brands and checked against WhisperGraph. They exist as registered hostnames right now. The current pipeline’s TLD-swap walks ASCII TLDs only, and there is no transliteration algorithm at all. So the whole surface is a blind spot. Attackers are not blind.

merck.닷컴transliteration
facebook.公司semantic
tesla.公司semantic
balenciaga.닷컴transliteration
douyin.集团semantic
amazon.닷컴transliteration
аппле.comCyrillic
הם.comHebrew
לג.comHebrew
로체.comHangul
プラダ.comKatakana
디올.comHangul
where this goes

The conflated root zone and the transliteration generator feed two new algorithms in the variant engine, and the cross-language equivalence is written up to ride on the Root Zone Label Generation Rules, the existing ICANN mechanism for same-entity variant TLDs. The linguistic axis and the visual axis are the same problem seen from two sides. A name a person trusts, rebuilt out of parts a machine calls different. The person keeps trusting it. That is the whole trick.

how we know

Drawn, measured, and checked live.

The back of the file. Every glyph on this page is a real bitmap off a real font. Every threat verdict is a live lookup. Nothing here is from memory.

01

Draw the real fonts

We draw every domain-relevant Unicode codepoint through the real fonts each browser paints into the address bar. Roboto + Noto for Chrome, San Francisco for Safari and iOS, Segoe UI for Edge. Down the same HarfBuzz + FreeType shaping path the browsers walk.

nothing drawn from memory
02

Measure. Do not guess

We compare two glyphs as drawn: pixel intersection-over-union and structural similarity. A pair lives only if it collides in that font. Unicode’s font-agnostic confusables that come out looking different, we throw away.

iou + ssim, per cell
03

Check it against the real machine

We checked the offline renders against what CoreText and DirectWrite actually paint, and they matched (median IoU ≈ 0.995). The Apple cell was frozen on a real Mac. The Windows cell on a real Windows 11 machine.

gate PASS · IoU 0.995
04

Find it in the wild

We checked font-grounded look-alikes of a 500-brand panel against WhisperGraph, all 2.6 billion hostnames, to see which a stranger had bought and which sit on threat feeds right now. The browser-conditional pattern holds on the tier that does not depend on the threshold. It is not a number we tuned.

live threat lookup
font-grounded3 browser cells2,402 confusable pairs267 registered look-alikeslive WhisperGraph threat intel
the gift · take it

Here is the list. It is yours.

Unicode keeps a list of letters that can be mistaken for each other. It is a good list. But it does not know which font your browser uses, so it guesses. It says these two might fool someone, in some typeface, somewhere. Nobody measured the typeface you are actually looking at. So we did. We drew every domain-relevant codepoint through the real fonts and kept only the pairs that come out as the same pixels. Not might. Do. 2,402 of them. Directed, not closed over itself, each one scored, each one marked strict or at-a-glance.

Take them. We are not selling anything and there is no form to fill out. You found this page; the file is right here. We made it so people would stop typing their password into a stranger’s copy of their bank, and that only works if you have it. So here it is. Free, forever. You do not have to ask us. That is the whole reason it exists. That is all we wanted.

CC‑BY‑4.0. Free, forever, no permission needed. Use it in anything, even something you sell. The one thing we ask is that you say where it came from. Built from Unicode 16.0 and real font rendering. We ship codepoints and scores, never the font binaries.

the filesview repo
github.com/whisper-sec/visual-confusables →

Only 400 of the 2,402 fool you in all three browsers. A letter that vanishes on Chrome is a perfect forgery on Safari. So there is one file per browser. Because the web does not look the same to everyone, and a list that pretended it did would lie to you.