Unicode's confusables.txt and NFKC normalization disagree on 31 characters
3 days ago
- #Normalization
- #Unicode
- #Security
- 同形异义字攻击利用不同书写系统中视觉相同的字符,例如西里尔字母'а'与拉丁字母'a'。
- Unicode的confusables.txt通过映射约6,565个字符到其视觉等效字符提供防御机制。
- NFKC规范化会合并兼容性变体(如全角字母→ASCII字符),推荐用于slug验证场景。
- confusables.txt中有31个字符与NFKC规范化存在冲突,这些字符被映射到不同的拉丁字母/数字。
- 示例:长S字符(��)在confusables.txt中被映射为'f'(视觉相似),但在NFKC中规范化为's'(语义正确)。
- 大写字母I的16种变体在confusables.txt中映射为'l',但通过NFKC会规范化为'i'。
- 数字0的7种变体在confusables.txt中映射为'o',但NFKC会将其规范化为'0'。
- 数字1的7种变体在confusables.txt中映射为'l',但NFKC会规范化为'1'。
- 冲突根源在于confusables.txt侧重视觉相似性,而NFKC侧重语义一致性。
- 简单串联两种处理可能导致死代码(31条冲突条目)或处理顺序颠倒时产生错误结果。
- 解决方案:过滤confusables.txt以排除NFKC已处理的字符,将条目从~6,565缩减至~613。
- 推荐处理流程:NFKC规范化→NFKC感知的混淆字符映射→混合书写系统检测拒绝。
- 文档缺口:Unicode标准未明确说明confusables.txt与NFKC的交互关系。
- 自动化生成脚本可创建NFKC感知的混淆字符映射表,确保跨Unicode版本的可复现性。