Which link is fake?
哪個連結是假的?
Two links that read the same. The first uses the Latin a (U+0061); the second swaps in the Cyrillic а (U+0430).
兩個看起來一樣的連結。第一個用的是拉丁字母 a(U+0061),第二個換成了西里爾字母 а(U+0430)。
An IDN homograph attack swaps a letter in a domain for a lookalike from another script, such as Cyrillic а for Latin a. This demo lets coworkers see it for themselves, then shows how the trick is used and how to defend against it.
IDN 同形異義字攻擊,是把網域裡的字母換成其他文字裡長得一模一樣的字母,例如用西里爾字母 а 取代拉丁字母 a。這個 demo 讓同事親眼看一次,再說明攻擊者怎麼利用、又該怎麼防。
Domain names can contain letters from many scripts, and browsers convert those names to an ASCII form that starts with xn-- (Punycode, RFC 3492). An attacker registers a name that swaps one Latin letter for its Cyrillic twin. People see the familiar spelling; the computer sees different code points and connects to a different domain.
網域名稱可以包含各種文字的字母,瀏覽器會把這類名稱轉成以 xn-- 開頭的 ASCII 形式(Punycode,RFC 3492)。攻擊者註冊一個把某個拉丁字母換成西里爾「雙胞胎」的網域:人眼看到的是熟悉的拼法,電腦看到的卻是不同的碼位,連到的也是另一個網域。
User vigilance alone cannot defend against this.
單純靠使用者警覺,幾乎不可能防禦。The page works like a short live session. It opens with a question and closes with a checklist.
整個頁面就像一堂簡短的現場課:從一個問題開始,用一份清單收尾。
Two links that read the same. The first uses the Latin a (U+0061); the second swaps in the Cyrillic а (U+0430).
兩個看起來一樣的連結。第一個用的是拉丁字母 a(U+0061),第二個換成了西里爾字母 а(U+0430)。
Click the second link and the address bar shows an xn-- Punycode name, and the browser may warn you. The fake link is not meant to load.
點第二個連結,網址列會出現 xn-- 開頭的 Punycode 名稱,瀏覽器也可能跳出警告。假連結本來就不會正常開啟。
The demo's own seven-step reconstruction of the Booking.com “reservation hijack” scams that the BBC reported in April 2026: stolen hotel logins, guest data, a message posing as the hotel, and a lookalike payment link.
demo 自己整理的七步攻擊鏈,對應 BBC 在 2026 年 4 月報導的 Booking.com「訂房劫持」詐騙:飯店後台帳密被偷、房客資料外流、有人冒充飯店傳訊息,最後附上一個仿冒的付款連結。
A character table explains why the eye cannot tell the difference, and a checklist covers what people and security teams can do.
用字元對照表說明為什麼肉眼分不出來,再用一份清單整理個人與資安團隊各自能做的事。
The fake link swaps one letter for a Cyrillic lookalike. The table lists five pairs.
假連結把一個字母換成西里爾字母的形近字。對照表列了五組。
Latin a
examplebank.example uses U+0061 for the first a.
Cyrillic a
The fake href writes U+0430 in that same spot. The page does not encode it first.
Same on screen
The table calls the pairs for a, c, e, o, and p identical.
Two hosts
One code point of difference means two labels under .example.
拉丁的 a
examplebank.example 裡第一個 a,是 U+0061。
西里爾的 a
假連結的 href 在同一個位置直接寫 U+0430。頁面沒有先編碼。
螢幕上看一樣
對照表把 a、c、e、o、p 這五組都標成一模一樣。
兩個主機名稱
差一個碼位,就是 .example 底下兩個不同的名稱。
This page does not encode the name. The browser turns it into Punycode (RFC 3492) before sending the label.
頁面自己不會編碼。送出前,瀏覽器才把它轉成 Punycode(RFC 3492)。
Raw label
The fake label is ex, then U+0430, then mplebank. The suffix .example is a separate label.
Copy ASCII
Punycode copies the ASCII letters in order and gets exmplebank.
Record the gap
After a hyphen, the label records the missing letter and its place. Here that suffix is 0qi.
Add xn--
IDNA adds the prefix xn-- to that label only, giving xn--exmplebank-0qi.example.
原本的標籤
假標籤是 ex、接著 U+0430、再來 mplebank。後綴 .example 是另一段。
先留 ASCII
Punycode 依序抄下 ASCII 字母,得到 exmplebank。
記下缺的字
連字號後面記下被拿掉的字和位置。這個名稱的後綴是 0qi。
補上 xn--
IDNA 只在這段前面加 xn--,變成 xn--exmplebank-0qi.example 這個主機名稱。
Both links on the page are real links, but neither one opens a site.
頁面上兩個都是真的連結,但點了都不會打開任何網站。
Both labeled
The question asks which one is fake. The badges already mark which one is real and which is fake.
Open the fake
Its href is the Unicode lookalike, with rel=noopener and target=_blank.
Read the bar
The hint says the address bar will show the xn-- host, and the browser may warn you.
Nothing loads
RFC 2606 reserves .example, so neither name is registered and neither one resolves.
兩個都標好
問題在問哪一個是假的。徽章已經標出哪個是真的、哪個是假的。
打開第二個
它的 href 是 Unicode 形近名稱,並帶 rel=noopener 和 target=_blank。
讀網址列
頁面說網址列會出現 xn-- 主機名稱,瀏覽器也可能跳出警告。
沒有網站
兩個名稱都在 .example。RFC 2606 保留這個網域,所以不能註冊,也不會解析。
The letters on screen can match a familiar name while the request uses a different host.
螢幕上的字母可以像一個熟悉的名稱,請求用的卻是另一個主機。
Visible text
The fake link's visible text is the lookalike spelling, which matches the real name to the eye.
Browser policy
The checklist tells you to watch for xn--, and it names Chrome, Edge, and Firefox.
Punycode host
A lookup that resolved would use xn--exmplebank-0qi.example. This demo never resolves.
畫面上的字
假連結畫面上的字是形近拼法,肉眼和正牌名稱一樣。
瀏覽器政策
清單要你留意 xn--,並寫了 Chrome、Edge、Firefox 的 IDN 顯示政策。
另一個主機
如果名稱能解析,請求會用 xn--exmplebank-0qi.example。這個 demo 不會解析。
Taken from the demo's closing section. The first five are habits anyone can keep; the last one is for security and IT teams.
整理自 demo 的最後一段。前五項是每個人都做得到的習慣,最後一項是給資安與 IT 團隊的。
Check the root domain at the right end of the address, not the words in front of it. secure-example.com is not example.com.
檢查網址最右邊的根網域,不要被前面那串字騙了。secure-example.com 不是 example.com。
A lookalike name often shows up as xn-- Punycode. When the browser shows that form instead of the familiar spelling, its homograph protection is working.
仿冒網域常會以 xn-- 開頭的 Punycode 顯示。瀏覽器不顯示熟悉的拼法、改顯示這種形式,就代表它的同形字防護正在運作。
xn--Open the app, type the address, or use a bookmark. Any message that asks for a wire transfer is almost always a scam.
自己打開 App、手動輸入網址,或用書籤。任何要求銀行轉帳的訊息,幾乎都是詐騙。
bookmarkWith multi-factor authentication, a stolen password alone does not get in. FIDO2 keys and passkeys also resist credential phishing.
有了多因素驗證,只偷到密碼也登不進去。FIDO2 金鑰與 passkey 還能抵擋帳密釣魚。
FIDO2 · passkeyChrome, Edge, and Firefox ship an IDN display policy for homograph detection. Staying current keeps that check working.
Chrome、Edge、Firefox 都內建 IDN 顯示政策來偵測同形字,保持更新,這道檢查才會持續有效。
IDN display policyDefensive domain registration, DMARC, SPF, and DKIM, DNS monitoring, and regular phishing drills. A SOC can watch newly registered and Punycode domains and scan for brand lookalikes with dnstwist.
防禦性註冊網域、DMARC / SPF / DKIM、DNS 監控與定期釣魚演練。SOC 可以監控新註冊的網域與 Punycode 網域,並用 dnstwist 掃描仿冒自家品牌的變體。
DMARC · dnstwistPreview it locally, then deploy your own copy. vercel.json adds security headers and keeps the page out of search results.
先在本機預覽,再部署自己的版本。vercel.json 會加上安全標頭,並讓頁面不被搜尋引擎收錄。
Open index.html in a browser. Or clone the repository, serve the folder, and visit http://localhost:8000.
直接用瀏覽器開啟 index.html;或 clone repo 後在資料夾裡啟動本機伺服器,再開 http://localhost:8000。
cd idn-homograph-example python3 -m http.server 8000
The first deploy of a new project goes straight to production. After that, vercel makes a preview and vercel --prod updates production.
新專案第一次部署會直接上正式環境;之後執行 vercel 只會產生預覽版,要更新正式版請用 vercel --prod。
npm install -g vercel vercel vercel --prod
Import the repository at vercel.com/new with Framework Preset Other and empty build settings, or drop the folder on vercel.com/drop.
在 vercel.com/new 匯入 repo,Framework Preset 選 Other、建置設定留空;或直接把資料夾拖到 vercel.com/drop。
Written in April 2026 as a study note for showing coworkers the attack, and changed in October 2026 to use a fictional bank. Small and finished, and the Vercel copy is still live.
2026 年 4 月寫給同事看的學習筆記,2026 年 10 月改用虛構的銀行當範例。規模小、內容已完成,Vercel 上的版本仍在線上。
More from Ted Huang. Every public project has a page like this one, in English and Traditional Chinese.
Ted Huang 的其他作品。每個公開專案都有一頁像這樣的中英雙語介紹。
All projects →全部專案 →