Link-mismatch warning is bypassed by adding a word to the link text, or by using a shared hosting domain (pages.dev, github.io…) #335

Closed
opened 2026-10-05 23:37:41 -04:00 by jared · 0 comments
Owner

utils/linkSafety.ts (#122) catches the classic shapes, measured with the real analyzeLink:

"https://chat.lotusguild.org/login"  → https://evil.example/login                 FLAGGED
"https://chat.lotusguild.org"        → https://chat.lotusguild.org@evil.example/  FLAGGED
"chat.lotusguild.org"                → https://chat.lotusguild.org.evil.example/  FLAGGED
"paypal.com"                         → https://xn--pypal-4ve.com/                 FLAGGED

Two easy bypasses:

"Log in at chat.lotusguild.org"      → https://evil.example/   not flagged
"chat.lotusguild.org (official)"     → https://evil.example/   not flagged
"lotusguild.pages.dev"               → https://evil.pages.dev/ not flagged
"alice.github.io"                    → https://evil.github.io/ not flagged
  1. Any whitespace in the text disables the check. hostFromText returns null when /\s/.test(text). A phish just writes a sentence ("Log in at …", "… (official)") around the trusted name.
  2. Multi-tenant hosting suffixes count as one site. registrableDomain uses a hand-made two-label list instead of the Public Suffix List, so x.github.io, x.pages.dev, x.netlify.app, x.vercel.app, x.web.app, x.blogspot.com, x.herokuapp.com etc. all collapse to the shared suffix and any two sites on it "match".

Fix:

  • Scan the text for host-like tokens (the same HOST_LIKE pattern, applied per word). If any token's registrable domain differs from the href's, flag it, ignoring the plain words around it.
  • Use the PSL (psl / tldts, both small) for registrableDomain, including the private section, which is what covers github.io / pages.dev.
  • Add the cases above to linkSafety.test.ts.

Found in the October 2026 client audit (Playwright against a local Synapse + LiveKit stack, plus code reading). Code refs are at cinny 30e2dbcd, cinny-desktop 8f67ec7, element-call 3b0050e8.

`utils/linkSafety.ts` (#122) catches the classic shapes, measured with the real `analyzeLink`: ``` "https://chat.lotusguild.org/login" → https://evil.example/login FLAGGED "https://chat.lotusguild.org" → https://chat.lotusguild.org@evil.example/ FLAGGED "chat.lotusguild.org" → https://chat.lotusguild.org.evil.example/ FLAGGED "paypal.com" → https://xn--pypal-4ve.com/ FLAGGED ``` Two easy bypasses: ``` "Log in at chat.lotusguild.org" → https://evil.example/ not flagged "chat.lotusguild.org (official)" → https://evil.example/ not flagged "lotusguild.pages.dev" → https://evil.pages.dev/ not flagged "alice.github.io" → https://evil.github.io/ not flagged ``` 1. **Any whitespace in the text disables the check.** `hostFromText` returns `null` when `/\s/.test(text)`. A phish just writes a sentence ("Log in at …", "… (official)") around the trusted name. 2. **Multi-tenant hosting suffixes count as one site.** `registrableDomain` uses a hand-made two-label list instead of the Public Suffix List, so `x.github.io`, `x.pages.dev`, `x.netlify.app`, `x.vercel.app`, `x.web.app`, `x.blogspot.com`, `x.herokuapp.com` etc. all collapse to the shared suffix and any two sites on it "match". **Fix:** - Scan the text for host-like *tokens* (the same `HOST_LIKE` pattern, applied per word). If any token's registrable domain differs from the href's, flag it, ignoring the plain words around it. - Use the PSL (`psl` / `tldts`, both small) for `registrableDomain`, including the private section, which is what covers `github.io` / `pages.dev`. - Add the cases above to `linkSafety.test.ts`. --- _Found in the October 2026 client audit (Playwright against a local Synapse + LiveKit stack, plus code reading). Code refs are at cinny `30e2dbcd`, cinny-desktop `8f67ec7`, element-call `3b0050e8`._
jared added the priority: lowsecurityarea: messaging labels 2026-10-05 23:37:41 -04:00
jared closed this issue 2026-10-16 19:59:20 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#335