语言的边界:从 SQL 注入到大模型安全的范式转移

作为一名安全工程师,在处理漏洞的过程中,我始终认为安全的本质是对边界的定义与捍卫。而语言,正是构建这些边界的基石。

从早期的 SQL 注入到如今的大模型(LLM)Prompt Injection,表面上看是攻击手法的演变,实则是计算架构从确定性(Deterministic) 向 **概率性(Probabilistic)**迁移时,语言边界控制权的根本性丧失。

1. 确定性系统的“语义逃逸”

回顾 SQL 注入,很多人认为它只是过滤不严。但从语言学的角度看,它的本质是控制流(Control Flow)与数据流(Data Flow)的混淆

在 SQL 这种形式化语言中,解释器依赖特定的字符(如单引号 ')来进行词法分析,构建抽象语法树(AST)。攻击者插入的 ' OR '1'='1,实际上是在利用解释器的词法规则,强行闭合了数据节点,并在 AST 中生成了新的逻辑分支

Log4j 漏洞(Log4Shell)则更为激进。它不仅仅是语义修改,而是利用了 ${jndi:...} 这种递归解析机制,将数据直接提升为代码。这种“数据即代码”的特性,本质上是因为语言设计者在数据通道中保留了过高的图灵完备性

在确定性系统中,防御是可解的。预编译(PreparedStatement)之所以能根治 SQL 注入,是因为它在协议层面将 SQL 模板(指令)与参数(数据)分开发送。在解析阶段,AST 的结构已经被固定,数据无论如何变化,都无法改变 AST 的拓扑结构。这是形式化语言给予我们的“上帝视角”——我们可以精确定义边界。

2. 概率性系统的“维度攻击”

大模型的出现,彻底打破了这种防御范式。

LLM 不是一个解析器,它是一个基于统计学的预测机。在 Transformer 架构中,无论是 System Prompt(指令)还是 User Input(数据),在进入模型前都会被 Tokenizer 转换,并被“压扁”在同一个高维向量空间中。

这意味着,在 LLM 内部,指令和数据在物理上是同构的。 它们只有权重的区别,没有性质的区别。不存在一个特殊的寄存器用来只存指令,也不存在一块内存只存数据。

这就是 Prompt Injection 无法被完美防御的理论根源:

  1. 没有独立的控制信道:我们无法像 SQL 预编译那样,物理隔离指令和数据。
  2. 自然语言的歧义性:自然语言本身就是**带内信令(In-band Signaling)**系统。没有任何一个字符(如引号)能像在 C 语言里那样具有绝对的定界作用。
  3. 对抗本质的改变:攻击者不再是寻找解析器的逻辑 Bug,而是在高维特征空间中寻找对抗样本。Prompt Injection 本质上是在通过微调输入的向量方向,将模型输出的概率分布推向攻击者期望的(恶意)区域。

这不再是语法分析的问题,这是信息论的问题。当信息熵过高,接收方(LLM)无法准确解构发送方(开发者)的真实意图。

3. Agent 架构下的权限失控

如果说 LLM 的幻觉只是“嘴炮”,那么 Agent 和 MCP(Model Context Protocol)的引入,则让 LLM 具备了副作用(Side Effect)。这让安全风险从“内容安全”升级到了“系统安全”。

在 Agent 架构中,LLM 扮演了决策中枢的角色。这导致了经典的**混淆代理人(Confused Deputy)**问题的复活:

  • 攻击者(User)通过 Prompt Injection 控制了 代理人(LLM)。
  • 代理人(LLM)持有合法的凭证,向 受害者(MCP Server)发起请求。
  • 受害者(MCP Server)看到请求来自授信的 LLM,于是执行了操作(如删除文件)。

这里的核心矛盾在于:我们把系统最高的决策权(Root of Trust),交给了一个基于概率、不可解释且极易受控的黑盒(LLM)。

4. MCP Server 的防御哲学

针对 MCP Server 的安全设计,必须放弃“LLM 能理解安全规则”的幻想,回归到最底层的**零信任(Zero Trust)**原则。

MCP Server 必须假设上游的 Agent 已经沦陷。

  1. 意图与能力的解耦:LLM 只能表达“我想读文件”(意图),但 MCP Server 必须校验“你能不能读这个文件”(能力)。这种校验不能依赖 LLM 的自我审查,必须在 MCP 层通过确定性的代码逻辑(如 ACL、RBAC)强制执行。
  2. 降维打击:Agent 的输出往往是 JSON 等结构化数据。这其实是一个将**自然语言(高维/模糊)强制坍缩为形式化语言(低维/精确)**的过程。MCP Server 应利用这一过程,对 JSON Schema 进行极度严格的校验,任何不符合预期的字段都应导致请求拒绝,而不是让 LLM 去“猜”如何处理。
  3. 执行沙箱:对于涉及代码执行或复杂逻辑的 Tool,必须在隔离的沙箱环境中运行。不能让自然语言的模糊性渗透到宿主机的操作系统层面。

结语

从 SQL 注入到大模型安全,我们面对的始终是同一个问题:如何在不可信的输入中,建立可信的计算逻辑。

只不过,以前我们通过形式化语言的语法树来锁定边界;而在 AI 时代,面对概率性的混沌,我们需要用更严苛的外部架构约束,去规训那不可控的智能。安全工程师的战场,正从代码审计室,转移到了概率与架构的无人区。

一些小思考

Dan❤Anan
Built with Hugo
主题 StackJimmy 设计