资讯动态

大模型同形字符欺骗防御:不可见 Unicode 与零宽字符注入的清洗方案

发布时间:2026/10/4 20:25:20 来源:尧图企业网站定制
大模型同形字符欺骗防御不可见 Unicode 与零宽字符注入的清洗方案在网络安全对抗中字符编码层面的隐写与欺骗是一门历史悠久的传统手艺。而在大语言模型LLM与生成式 AI 基础设施普及的今天这种古老的攻击手法正在自然语言语义边界上焕发全新的破坏力。很多安全团队为大模型搭建的前置过滤网关往往直接建立在普通的 UTF-8 字符串正则匹配上。例如风控策略中明确规定禁止出现某些高危指令或敏感实体词汇。然而Unicode 字符集包含超过 14 万个字符其中不仅存在大量在视觉渲染上与英文字母毫无二致的“同形异义字Homoglyphs”还存在成百上千个在终端或渲染窗口中完全不占任何像素的“零宽字符Zero-Width Characters”与不可见控制字符Invisible Control Characters。攻击者只需将几个零宽字符插在敏感提示词中间或者将英文字母替换为西里尔字母、希腊字母传统的正则过滤器与基于词表的敏感词库就会瞬间“睁眼瞎”。但与此同时大模型底层的分词器Tokenizer在对输入文本进行切词与字节级解码时却能依然凭借其庞大的泛化空间还原出真实的恶意意图。要守住大模型的输入边界必须在所有业务逻辑生效之前建立底层的**“Unicode 字符归一化”与“不可见字符深度清洗”管线**。两大核心欺骗手法拆解同形字符与零宽字符注入攻击示意 ┌────────────────────────────────────────────────────────┐ │ 1. 零宽字符注入 (Zero-Width Injection): │ │ 人眼/渲染所见: ignore previous instructions │ │ 底层真实十六进制: │ │ i\u200Bgn\u200Core\uFEFF pre\u200Dvious... │ │ 效果: 正则单词匹配完全断裂失效但分词器仍能感知语义 │ ├────────────────────────────────────────────────────────┤ │ 2. Unicode 同形异义字欺骗 (Homoglyph Attack): │ │ 拉丁字母 a (U0061) vs 西里尔字母 а (U0430) │ │ 拉丁字母 p (U0070) vs 西里尔字母 р (U0440) │ │ 构造: рrоmрt (全采用西里尔字符视觉 100% 相同) │ │ 效果: 传统 ASCII 黑名单全部绕过 │ └────────────────────────────────────────────────────────┘1. 零宽字符Zero-Width Characters的隐写断词Unicode 中定义了一批专门用于复杂排版如连接波斯语、阿拉伯语字母的不可见字符U200BZero-Width Space零宽空格U200CZero-Width Non-Joiner零宽非连接符U200DZero-Width Joiner零宽连接符UFEFFByte Order Mark零宽无中断空格攻击者将这些不可见字符随机插入到system、admin、ignore等敏感单词之间。由于这些字符在屏幕上不可见对于终端用户和肉眼审核员来说句子看起来毫无破绽。但对于简单的字符串比较函数如 Python 的in或正则\bignore\b由于中间插入了字节匹配彻底落空。2. 同形异义字Homoglyphs的视觉伪造Unicode 字符集为了覆盖全球所有文明的语言收录了大量在字形Glyph上与拉丁字母极其相似甚至完全重合的字符。例如西里尔字母的аU0430、оU043E、еU0435。攻击者用这些同形字混写提示词能够以极低成本绕过基于字符串哈希或精确字典的规则库。生产级防御Unicode 规范化与深度清洗流水线防御同形字符与不可见字符欺骗核心必须依赖国际 Unicode 联盟制定的规范化标准Normalization Forms并结合严格的控制字符过滤。1. Unicode NFKC 兼容等价分解与重组Unicode 提供了四种标准规范化算法NFD、NFC、NFKD、NFKCNormalization Form KC。在安全审计中我们必须强制采用NFKC 算法它不仅会将组合字符如带有声调符号的字母压缩为预合成字符更关键的是它会对视觉同形但编码不同的兼容性变体Compatibility Characters如全角字符、上标数字、环形字符执行强行降维映射还原为其基准 ASCII 字符2. 生产级 Python 清洗网关实现下面是在大模型请求入口处必须部署的字符规范化处理模块import unicodedata import re from typing import Tuple class UnicodeSanitizer: def __init__(self): # 常见零宽字符与双向控制字符Bidi Controls黑名单正则 # 包括零宽空格、双向覆盖字符RLO/LRO 用于颠倒文字方向等 self.invisible_and_bidi_pattern re.compile( r[\u200B-\u200D\uFEFF\u200E\u200F\u202A-\u202E\u2060-\u206F] ) def sanitize_prompt(self, raw_user_prompt: str) - Tuple[str, bool]: 对输入文本进行彻底的字符清洗与同形归一化 返回: (清洗后的标准纯净文本, 是否检测到恶意字符注入) tampered_detected False # 1. 检查并剥离所有零宽不可见字符与双向文本控制符 if self.invisible_and_bidi_pattern.search(raw_user_prompt): tampered_detected True clean_text self.invisible_and_bidi_pattern.sub(, raw_user_prompt) else: clean_text raw_user_prompt # 2. 执行 Unicode NFKC 兼容性规范化 # 这一步会将全角字符、特殊变体字符强制折叠为标准通用 ASCII/Unicode normalized_text unicodedata.normalize(NFKC, clean_text) # 3. 过滤掉所有无法打印的 C 类别Other / Control字符仅保留换行与制表符 sanitized_chars [] for char in normalized_text: category unicodedata.category(char) # Cc: 控制字符 (Control), Cf: 格式字符 (Format), Cs: 代理区 (Surrogate), Co: 私用区 (Private Use) if category.startswith(C): if char in [\n, \r, \t]: sanitized_chars.append(char) else: tampered_detected True # 丢弃异常控制字符 else: sanitized_chars.append(char) final_prompt .join(sanitized_chars) return final_prompt, tampered_detected生产落地的三项安全红线清洗操作必须位于所有前置护栏的最顶端任何敏感词过滤、意图分类器、AST 语法分析器、RAG 向量检索模型其接收到的输入文本必须是已经通过UnicodeSanitizer彻底清洗过的纯净文本。如果把字符清洗放在规则匹配之后整套防御体系等于在第一道关卡前就缴械投降。严防“双向覆盖字符Bidi Attack”破坏代码审查Unicode 包含专门用于阿拉伯语排版的双向文本字符如\u202ERLO强制从右向左渲染。攻击者在 Prompt 中注入 RLO 字符可以让屏幕上看起来是access_granted False的代码在物理执行层面其实是access_granted True。对任何输入中出现的 Bidi 控制字符必须执行一刀切的直接抹除。记录恶意字符注入的安全风控埋点如果一个普通用户的正常业务咨询中频繁出现\u200B零宽空格这绝非偶然必然是黑客利用自动化脚本进行的对抗性探测。网关层检测到此类注入后应当对该会话的 IP 与用户 UID 进行高风险标记并在风控侧提升其挑战门槛。安全攻防的本质是比拼谁能对更底层的协议与编码标准保持透彻的认知。把字符流的裂隙彻底焊死大模型防御体系才能在形形色色的文字迷彩面前立于不败之地。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑