← AI 应用上线 · 第 1 篇

提示注入防护:把不可信内容留在数据边界内

识别检索文档和工具结果中的间接指令,在程序侧限制工具、权限和资源访问。

学完这一篇,你能做到

区分内容与授权,设计应用层允许清单,而不是依赖提示词识别所有攻击。

提示注入的问题,是不可信内容试图改变系统的行为。它可能出现在用户输入,也可能藏在检索文档、网页、图片识别文本和工具返回结果里。

仅仅告诉模型“不要被攻击”,并不能形成稳定的安全边界。真正重要的是:外部内容能影响什么,程序允许它触发什么。

区分内容与授权

一段资料可以提供答案证据,但不能因为写了“请调用管理员工具”,就获得执行权限。引用来源可靠,也不意味着来源中包含的每句话都能成为系统规则。

OWASP 对提示注入的说明强调,RAG 与微调不能完全解决这类风险。把资料接入模型时,同时要保留其信任等级和来源。

工具权限、用户身份和允许资源来自可信应用逻辑,不来自模型对资料的总结。

限制能力,比猜测攻击文本更可靠

让模型选择预先登记的资源 ID,通常比允许它提供任意 URL 更容易控制。网络访问还需考虑重定向、DNS 解析和内部地址,不能只用字符串判断 URL 是否安全。

写操作应该有独立授权。凭据留在执行器内部,只给模型完成任务所需的结果,不把令牌拼进上下文。

对输出长度、工具次数与总时间设置上限。外部内容即使让模型进入异常路径,也不应获得无限资源。

用资源允许清单练习边界

下面的本地示例不请求网络。模型只能提出一个资源 ID,应用从预先授权的资料中读取内容。资源字典和权限集合都来自可信代码。

resources = {"public-guide": "A short public engineering guide."}

def read_document(arguments, granted_resources):
    if not isinstance(arguments, dict) or set(arguments) != {"resource_id"}:
        raise ValueError("invalid arguments")
    resource_id = arguments["resource_id"]
    if not isinstance(resource_id, str):
        raise ValueError("resource identifier required")
    if resource_id not in granted_resources or resource_id not in resources:
        raise PermissionError("resource not authorized")
    return resources[resource_id]

assert read_document({"resource_id": "public-guide"}, {"public-guide"})
try:
    read_document({"resource_id": "private-config"}, {"public-guide"})
except PermissionError:
    print("Unauthorized resource rejected")
else:
    raise AssertionError("unauthorized access accepted")

这个允许清单不能识别全部注入攻击。它的价值在于,即使模型被误导,也只能请求应用明确允许的资源。

把拒绝和异常也做成用例

准备包含间接指令的公开或构造资料,例如要求改用未授权工具、读取额外资源或隐藏执行过程。观察执行器是否仍然执行原有权限规则。

检查缓存和跨任务状态,确保一个任务拿到的工具权限不会泄漏给另一个任务。工具结果进入下一轮上下文时,仍保留外部数据身份。

发现攻击样本后,优先检查能力边界是否过宽,再补充提示词和检测手段。关键词过滤只能作为辅助层,不能替代授权。

下一步

列出你的应用可以读取和修改的资源,为每种能力写出允许范围。再用一个诱导访问额外资料的样本,检查程序能否阻止请求。

为结果不确定、权限被拒绝和需要人工确认设计明确状态。下一篇进一步观察这些任务的耗时和资源使用。

资料来源与延伸阅读

资料核验:2026-11-10。本文为原创工程讲解,教学示例不代表线上实测。