You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Homoglyph threat fires on any Cyrillic / Greek import: flag confusables (UTS #39 skeleton), not scripts #3885
Part of epic #3811. Found by the Unicode Gauntlet (#3878 / PR #3881).
Problem
SecurityLens.THREAT_SIGNATURES["homoglyphs"] (gitgalaxy/security/security_lens.py) matches any import / from / require / include / fetch line that contains any Cyrillic (U+0400–04FF) or Greek (U+0370–03FF) character. The hit lands in sec_homoglyphs / threat_homoglyphs as a supply-chain spoofing threat.
As a result, a Russian, Ukrainian, Bulgarian, Serbian or Greek team's honest code is reported as an attack:
from данные import загрузить → threat
import αβγ → threat
import os # комментарий → threat (a comment on the import line)
In the gauntlet, the javascript, typescript and python × cyrillic / greek cells fail on threat_homoglyphs 0 -> 1 in every encoding, UTF-8 included.
A homoglyph attack is a name that looks Latin but isn't: rеquests with a Cyrillic е, аррӏе, or 𝐫𝐞𝐪𝐮𝐞𝐬𝐭𝐬 in mathematical bold. Unicode's security mechanisms (UTS #39) define that precisely:
mixed-script confusable: a token mixing Latin with look-alike letters;
whole-script confusable: a token made entirely of look-alike letters.
Neither definition covers "a token in another script".
Fix
Keep the regex as the cheap candidate finder, so its literal prefilter gate stays valid. Then count a candidate line only when it really carries a spoof:
a token (a maximal \w run) that is not ASCII but whose skeleton is pure ASCII. The skeleton is NFKC followed by a curated Cyrillic / Greek → Latin map taken from UTS chore(deps): bump parso from 0.8.6 to 0.8.7 #39confusables.txt: letters only, no digits, and no new dependency. That covers rеquests, аррӏе, importа and math alphanumerics;
or an invisible Hangul filler (U+3164, as today).
Out of scope: the typosquatting radar in galaxyscope (edit distance between import names) also feeds sec_homoglyphs. All 21 corpus files that carry a homoglyph count in the golden masters come from that radar, not from this regex. It works on ASCII names and isn't cultural.
Verification
Tests. Still flagged: import rеquests, from аррӏе import x, import 𝐫𝐞𝐪𝐮𝐞𝐬𝐭𝐬, U+3164, and the existing gate-parity sample importа os. No longer flagged: from данные import загрузить, import αβγ, from calc_αβγ import f, require('./жзи'), and an import line with a Cyrillic comment.
The existing gate-parity test still holds, since the prefilter is untouched.
Golden masters: expected byte-identical. The corpus has no non-ASCII import lines, so no count changes.
Unicode Gauntlet: the javascript / typescript / python × cyrillic / greek cells pass in every encoding, and the baseline is lowered.
Activity
#3885: lower the gauntlet baseline -- Cyrillic / Greek imports are no…
#3885: regenerate the gauntlet baseline after merging main -- 932 of …
#3885: a homoglyph is a confusable, not a script (UTS #39 skeleton) (#…