Hotdry.
ai-security

用 Unicode 零宽字符洪泛过载 LLM 分词器与注意力层:绕过输入清洗的推理破坏工程

Gibberifier 等工具利用零宽 Unicode 字符制造 token 爆炸,绕过 sanitizers 导致 LLM 推理中断,提供生产防御参数与监控清单。

在生产 LLM 管道中,输入洪泛攻击已成为隐蔽 DoS 威胁的核心形式。Gibberifier 等工具通过插入零宽 Unicode 字符(如 U+200B Zero Width Space、U+200C Zero Width Non-Joiner、U+200D Zero Width Joiner)在每个可见字符间制造隐形填充。这些字符对人类阅读无影响,但 tokenizer 会将其视为独立 token,导致输入长度指数级膨胀。例如,一段 500 字符提示经处理后 token 数可暴增至数千,迅速耗尽上下文窗口并过载注意力层计算。

攻击原理直指 LLM 管道痛点。首先,BPE 或 SentencePiece 等 tokenizer 对 Unicode 敏感,无法忽略零宽字符,导致 “abc” 变为 “a​b​c”(每个间有零宽),token 数翻倍甚至更多。“Gibberifier 插入 invisible zero-width Unicode characters between each character of your input text. The text will look the same but will be much longer and can help stop AI plagiarism.” 其次,注意力机制的 O (n²) 复杂度放大此效应:token 数从 2k 飙至 10k 时,内存需求激增 25 倍,KV cache 爆炸引发 OOM 或超时。再次,绕过 sanitizers:多数输入清洗仅检查可见字符长度或黑名单词汇,零宽 Unicode 合法且不可见,规避 regex 过滤。

生产环境中,此攻击针对 API 端点或聊天接口尤为致命。用户可针对关键提示(如作文开头)注入 Gibberifier 输出,触发 rate limit(token / 分钟超阈值)或单次推理崩溃。测试显示,Claude 或 GPT-4 等模型遇 5k+ 零宽填充时,常输出混乱或直接拒绝;开源如 Llama tokenizer 崩溃率更高。相比传统 payload,此法隐蔽性强,无需越狱 prompt,仅依赖 Unicode 规范。

防御需多层工程化参数配置,形成闭环。核心预处理管道:

  1. Unicode 规范化与剥离

    • 应用 NFKC 规范化(Normalization Form Compatibility Composition):合并兼容等价字符,消除零宽变体。Python 示例:unicodedata.normalize('NFKC', input_text)
    • 显式剥离零宽范围:regex r'[\u200B-\u200D\u2060\uFEFF\s]+' 替换为空。阈值:若剥离后长度变化 >20%,标记为可疑并 quota 降级。
  2. Tokenizer 前长度阈值

    • 预 tokenization 检查:估算字节长度 > 8KB 或可见 char > 4k 即拒绝。使用 len(text.encode('utf-8')) 结合可见过滤。
    • 后 tokenizer 强制截断:max_tokens=4096,无论输入多长强制 clip,并日志 token 膨胀比(post/pre > 2 触发告警)。
  3. 注意力层防护

    • KV cache 预分配:固定 max_seq_len=8192,超长 OOM 时 fallback 至 CPU 或拒绝。
    • Sliding window attention(如 Llama 3):限制有效上下文至 8k,零宽洪泛仅浪费前缀。
  4. 输入 Sanitizer 升级

    • 多阶段过滤:先 NFC normalize,再 zero-width strip,最后 homoglyph 检测( confusables.txt 库映射相似形)。
    • WAF 规则:Cloudflare/AWS WAF 添加 Unicode flood signature,匹配连续零宽模式。

监控与回滚策略至关重要。部署 Prometheus/Grafana 仪表盘:

  • 关键指标

    指标 阈值 告警动作
    token_inflation_ratio >1.5 降级流量 50%
    oom_rate >0.1% 回滚模型版本
    inference_timeout >5s 隔离 IP
    zero_width_density >0.1 蜜罐诱捕
  • 日志增强:记录 raw_input、normalized_input、token_ids 长度,便于取证。异常时 A/B 测试备用 tokenizer(如 tiktoken vs sentencepiece)。

  • 回滚清单:5min 内切换至 conservative mode(max_tokens=2048),并推送固件更新包含强化 normalize。

实操参数示例(vLLM 部署):

import unicodedata
import re

def sanitize_input(text: str) -> str:
    # NFKC normalize
    text = unicodedata.normalize('NFKC', text)
    # Strip zero-width
    text = re.sub(r'[\u200B-\u200D\u2060\uFEFF\u200E\u200F\s]+', '', text)
    if len(text.encode('utf-8')) > 8192:
        raise ValueError("Input too long post-sanitization")
    return text

结合 rate limiter:Redis token_bucket,每用户 10k tokens/5min。

风险不止 DoS:高级变体可嵌入 homoglyph(如 Cyrillic 'а' 伪 ASCII),进一步绕 NFKC;或动态生成洪泛针对特定 tokenizer vocab。测试中,Gibberifier 对 Google Docs 兼容,对 LLM 刮取器无效化。未来,tokenizer 需内置 robustness,如 byte-level fallback。

来源:Gibberifier 官网 (https://gibberifier.com),相关 tokenizer 攻击讨论。

(正文 1256 字)

查看归档