隐藏字符检测器
粘贴文本,检测器会高亮它找到的每一个不可见 Unicode 字符:零宽空格、连接符、方向标记、软连字符,每个都标注码点。
本工具检测的字符
检测器查找的常见不可见 Unicode 字符,以及每个的实际作用
标记换行机会。可被植入标识符内部,使其匹配方式与阅读时不同。
在阿拉伯语、波斯语等连笔文字里阻止字符连接。不可见,但改变相邻字形的连接方式。
emoji ZWJ 序列里的粘合剂。一个家庭 emoji 是四个 emoji 用三个 U+200D 字符连接而成,渲染为一个字形。
强制从左到右的文字方向,没有可见字形。在混合方向文字里合法;在 bidi 欺骗中被滥用。
强制从右到左方向。与 U+200E 一样是双用途字符。希伯来语和阿拉伯语需要它,钓鱼攻击里也被武器化。
不可见,直到在该位置换行时才渲染为连字符。从 PDF 复制时常被意外带入。
为什么不可见字符是个真实的问题
不可见 Unicode 字符的存在都有正当理由:换行控制、连笔文字连接、双向文本、可选连字符。但因为它们渲染为空,它们也是滥用的工具。Trojan Source 论文(CVE-2021-42574,2021 年 10 月披露)显示,双向覆盖字符能让源代码的编译结果与屏幕上读到的不一样。配套披露(CVE-2021-42694)涵盖同形字攻击,即用西里尔字母 а(U+0430)替换函数名里的拉丁字母 a(U+0061)。更贴近日常的情况是,零宽字符被植入用户名和标识符,让两个看起来一模一样的字符串比较结果为不同。按码点把这些字符标出来的检测器,是找到它们最快的方法,因为肉眼根本看不见。
这个工具的用处
一次彻底的扫描应该找什么
上面列出的六个字符最常见,但不是全部。彻底的扫描要覆盖多个范围。零宽格式字符 U+200B 到 U+200F 涵盖换行机会、连接符和方向标记。U+2060(字连接符)和 U+FEFF(字节顺序标记,出现在流中时)也是零宽。双向覆盖区块(U+202A 到 U+202E,加上 U+2066 到 U+2069)正是 Trojan Source 利用的部分。U+00AD(软连字符)在换行前不可见。谚文填充 U+115F 和 U+3164 以及盲文空白 U+2800 渲染为空但占一个单元,这让它们适合在明面上隐藏内容。易混淆字符检测是相关却独立的问题:西里尔字母 а 和拉丁字母 a 都可见,所以字符检测器不会标记它们。要查这个,需要对 Unicode 的 confusables 数据做比对,它把看起来相似的字符映射到一个归一化的骨架。
如何用好这个检测器
只粘贴你想检查的文本。一切都在你的浏览器里运行,不上传任何东西。
用颜色编码一眼区分字符类型:红色是 ZWSP,绿色是 ZWJ,橙色是 RLM,依此类推。
检测后,点击移除剥离所有不可见字符,再点复制干净文本拿到清理后的版本。
任何来自用户输入的用户名、slug 或标识符,在存储或比较之前都过一遍。
如果字符串比较失败而两个字符串看起来一模一样,把两个都粘贴进来。隐藏的 U+200B 是常见原因。
来自第三方的源代码,阅读前先扫 U+202A 到 U+202E。这些是 Trojan Source 背后的双向覆盖字符。
检测器如何工作
检测器完全以 JavaScript 在你的浏览器里运行。任何文本都不会离开你的设备,这一点在你粘贴敏感标识符或源代码时很重要。它在 Chrome、Firefox、Safari、Edge 以及桌面或移动端的任何现代浏览器里都能用。它扫描 U+200B 到 U+200F 范围内的零宽字符、U+202A 到 U+202E 和 U+2066 到 U+2069 的双向覆盖字符、字连接符 U+2060、软连字符 U+00AD,以及出现在文件首位置之外的 U+FEFF 字节顺序标记。注意它按码点标记不可见字符,不检测同形字。同形字是看起来像其他字符的可见字符。
