202510
ai-systems

欺骗分词器:字符级对抗攻击如何绕过LLM的安全防线

大型语言模型(LLM)的安全性不仅取决于语义理解,更隐藏在字符处理的底层细节中。本文揭示了利用Unicode和编码技巧进行字符级对抗攻击的机制、风险及其在工程实践中的防御策略。

当我们讨论大型语言模型(LLM)的安全性时,通常会想到语义层面的“越狱”或提示注入攻击。然而,一个更隐蔽、更底层的威胁正潜藏在模型处理文本的最初阶段——字符级操作。近期的研究揭示,通过精心构造的字符序列,攻击者可以有效地绕过许多先进的LLM安全护栏,这一发现对所有在生产环境中部署LLM的团队都敲响了警钟。

本文将深入探讨LLM在字符级文本操作方面的脆弱性,分析其内在机制,并为构建更具鲁棒性的AI系统提供可落地的工程化建议。

分词器:LLM的第一道,也可能是被绕过的防线

在理解字符级攻击之前,我们必须首先了解LLM是如何“阅读”文本的。人类按字词和句子阅读,但LLM处理的是“分词”(Token)。分词器(Tokenizer)是模型输入管道的关键组件,负责将原始的文本字符串转换为模型可以理解的离散化、数字化的分词ID序列。

这个转换过程包括文本规范化、词汇切分等多个步骤。例如,一个句子“Hello, world!”可能会被切分为["Hello", ",", " world", "!"]这样的分词。攻击者发现,通过在分词过程开始之前,对原始文本的字符进行微观层面的操纵,可以干扰分词器的正常工作,使其产生意想不到的分词结果,从而让有害指令“偷渡”到模型内部。这就像是伪造了进入戒备森严城堡的通行证,绕过了所有宏观层面的安全检查。

核心攻击向量:Unicode与编码的“武器化”

字符级对抗攻击并非单一技术,而是一系列利用文本数据表示复杂性的技巧。当前研究已验证的几种高效攻击向量包括:

  1. Unicode同形异义词(Homoglyphs):Unicode标准包含了来自世界各地的大量字符,其中许多字符在视觉上极为相似甚至无法区分,但其编码值却完全不同。例如,拉丁字母“A”(U+0041)与西里尔字母“А”(U+0410)在多数渲染字体下看起来一模一样。攻击者可以利用这一点,将一个有害词汇(如“bomb”)中的某个字符替换为其同形异义词。对于依赖关键词匹配的过滤器来说,这个被篡改的词汇可能不再是威胁,但对于在海量数据上预训练、见识过各种字符组合的LLM来说,它仍可能理解其背后的真实语义,从而执行恶意指令。

  2. 结构性扰动(Structural Perturbations):这类攻击通过插入在大多数情况下不可见的字符来分解或混淆有害指令。零宽度空格(Zero-Width Space, ZWSP)是其中最典型的代表。例如,攻击者可以将“获取用户密码”这个短语构造成“获[ZWSP][ZWSP][ZWSP][ZWSP][ZWSP]码”。在人类看来,文本显示没有任何异常,但对于分词器而言,原本完整的恶意短语被拆散,可能导致基于完整序列匹配的安全规则失效。

  3. 编码层攻击(Encoding Attacks):这是目前观测到的成功率最高的攻击类型之一。UTF-8作为最常见的字符编码,其规范允许同一个字符拥有多种有效的字节表示方式(例如,标准表示和“过长”表示)。许多安全系统在解码时为了兼容性会接受非标准的编码形式,但这恰恰为攻击者打开了方便之门。他们可以构造一个在字节层面看起来无害的序列,但经过解码后却能还原成恶意指令。研究表明,仅此一类攻击的成功率就可高达60%以上,远超许多传统的语义攻击方法。

一个令人警醒的发现是,模型的规模与其对字符级攻击的鲁棒性并不成正比。并非越大的模型就越安全,模型的具体架构、训练数据以及分词器的实现方式共同决定了其脆弱性程度。

工程实践中的防御策略

面对字符级攻击的威胁,我们不能仅仅依赖模型提供商的更新,而必须在自己的应用层构建纵深防御体系。以下是一些关键的防御措施:

1. 严格的输入规范化(Input Normalization)

这是防御此类攻击的第一道,也是最重要的一道防线。在将任何用户输入送往LLM之前,都应执行严格的规范化流程。

  • Unicode规范化:使用标准的Unicode规范化形式,如 NFKC (Normalization Form Compatibility Composite),它可以将兼容性字符(如同形异义词)统一为它们的标准形式。
  • 剥离不可见字符:显式地移除或替换所有非打印字符和控制字符,特别是零宽度空格等结构性扰动中常用的字符。
  • 白名单验证:如果业务场景允许,可以采用更严格的策略,即只允许输入包含在预定义字符集(如基本的字母、数字、标点)中的字符。

参数建议:在Python中,可以使用unicodedata.normalize('NFKC', user_input)来实现规范化。对于剥离不可见字符,可以结合正则表达式 re.sub(r'[​-‍]', '', text) 来完成。

2. 强化编码验证

绝不应信任客户端传入数据的编码方式。在接收到输入后,应立即在服务器端进行解码和重新编码的闭环验证。

  • 拒绝非标准编码:配置解码器,使其在遇到非规范的UTF-8序列(如过长表示)时直接抛出错误并拒绝该输入,而不是“宽容地”接受它们。
  • 一致性检查:将输入解码后,再用标准方式重新编码,比对结果是否与原始字节序列一致。任何不一致都可能意味着潜在的编码操纵。

3. 多层过滤与监控

  • 双重分词器检查:可以在安全流程中使用一个与模型不同的、配置更严格的“安全分词器”对输入进行预检查,分析其分词结果是否存在异常模式。
  • 异常模式监控:建立监控系统,检测输入中罕见字符、非标准编码或异常字节分布的出现频率。当这些指标超过预设阈值时,触发警报或执行更严格的审查流程。

结论

字符级对抗攻击揭示了LLM安全性的一个深刻事实:安全是一个覆盖从原始字节到最终语义的全栈问题。攻击者总会在系统中最薄弱、最不被注意的环节寻找突破口。对于开发者和安全工程师而言,这意味着必须将防御阵线前移,在数据进入模型核心之前,就通过严格的规范化、验证和过滤来“净化”输入。只有这样,我们才能在享受LLM强大能力的同时,有效抵御这些来自微观世界的隐形威胁,构筑真正值得信赖的AI应用。