在 Unicode 标识符欺骗攻击中,传统 confusables.txt 仅基于抽象字符映射,无法捕捉字体渲染导致的实际视觉混淆。像素级相似度量化是必要补充,能精确识别高风险 homoglyph 对,提供更可靠的安全检测基础。
渲染相似度的核心价值
Unicode TR39 定义的 confusables 是基于兼容性分解(如 NFKC)和人工审核的静态列表,但忽略了字体设计与渲染引擎的变异。例如,Cyrillic 'а' (U+0430) 在多数 sans-serif 字体中与 Latin 'a' 像素相同,却依赖具体字体实现。量化渲染相似度,能将 “潜在风险” 转化为可测指标:SSIM (Structural Similarity Index Measure) 分数从 -1 到 1,1 表示像素相同,0.7 以上视为高风险。这超越规范化,模拟真实浏览器 / 系统渲染场景。
项目方法与证据
confusable-vision 项目针对 TR39 中 1418 对非拉丁源字符到拉丁 a-z/0-9 目标,自动化渲染流程:
- 字体发现:使用 fontconfig 查询支持 Latin a-z 的系统字体(macOS 230 个,包括 74 standard、103 Noto 等)。
- 渲染管道:针对每个字符,渲染 48x48 灰度 PNG(node-canvas),仅渲染支持该字符的字体(减少 97% 计算)。
- 相似度计算:235,625 次 SSIM 比较,分 same-font(均值 0.536)和 cross-font(0.339)。灰度渲染优于彩色,因边缘对比保留更好。
关键发现:
- 96.5% 对 SSIM <0.7,非高风险(中位均值 0.322)。
- 82 对 max SSIM ≥0.999(像素相同),如 Cyrillic а/e/o/p/c/y/x 在 35-46 个标准字体中重用 Latin 字形轮廓。"confusable-vision 渲染 1418 对于 230 字体,发现 96.5% 非高风险,但 82 对像素相同。"
- Cyrillic 最危险(均值 0.447),Math Alphanumeric 最低(0.302)。
- 危险字体:Phosphate (67.5% 高风险对)、Copperplate (67.0%);安全字体:Zapfino (0%)。
扩展扫描发现 793 novel confusables(SSIM ≥0.7),74.5% 有效于 JS 标识符与 IDN,突出垂直笔画(如 l/i/j 占 47.5%)。
可落地工程参数与清单
实现类似管道,提供生产级参数:
1. 阈值配置
| 风险级别 | SSIM 阈值 | 行动 | 示例对数 |
|---|---|---|---|
| 像素相同 | ≥0.999 | 硬阻挡 | 82 对(Cyrillic) |
| 高风险 | 0.70-0.999 | 警告 / 审核 | 49 TR39 + 793 novel |
| 中风险 | 0.30-0.70 | 软警告 | 字体 / 上下文依赖 |
| 低风险 | <0.30 | 忽略 | 数学变体 |
- 聚合指标:对均值 SSIM、max same-font SSIM、≥0.95 字体比例。
- 脚本阈值:Cyrillic/Hebrew >0.40,Arabic/Math <0.30。
2. 实现清单(Node.js 示例)
// 依赖:fontconfig, node-canvas, ssim.js
1. 加载 TR39 confusables.txt,解析 1418 对。
2. fontconfig 查询:fc-list ':charset=61-7A' 获取字体列表。
3. 渲染:Canvas 48x48 灰度,DPI=72,hinting 默认。
4. SSIM 计算:skimage.ssim 或 JS 实现(luminance/contrast/structure)。
5. 缓存:JSON {pair: {font: ssim}},pHash 预滤(d<0.3 跳过)。
6. 并行:worker_threads,批次 1000 比较。
- 优化:预渲染 glyphs 缓存(~11k PNG),仅比较。
- 跨平台:Docker + FreeType,测试 Windows/Linux 字体集。
- 分辨率:48x48 基线,扩展 24/72px 测试 hinting。
3. 集成与监控
- Namespace-guard:confusableDistance () 加 visual_weight(max SSIM)。
- 浏览器检测:WebFont API 枚举用户字体,动态风险分。
- 回滚:若 SSIM >0.999,fallback punycode/ASCII。
- 监控点:
指标 阈值 告警 高风险对比例 >5% 字体更新 计算延迟 >1s/1000 缓存失效 Novel 发现 新增 > 10 扫描 Unicode 更新
4. 风险缓解清单
- 优先阻挡 same-font 高 SSIM(真实攻击场景)。
- 自定义字体审计:WebFont 前 SSIM 扫描。
- 上下文渲染:模拟 "paуpal" 字符串。
- 定期重跑:Unicode / 字体更新后。
此方法将 confusables 检测从二元提升为量化,提升精度 16x(793 novel)。在生产中,阈值 0.7 阻挡 3.5%+0.2% 高风险,false positive 降至 43%。
资料来源: [1] https://paultendo.github.io/posts/confusable-vision-visual-similarity/ [2] https://github.com/paultendo/confusable-vision [3] Unicode TR39 confusables.txt