Prompt Injection 为什么是 AI 应用的安全问题
Prompt Injection 指的是攻击者把恶意指令塞进用户输入、网页内容、文档、邮件或检索结果里,诱导模型忽略原有规则、泄露隐藏上下文、执行越权工具或生成危险输出。
它之所以特殊,是因为 LLM 会把“指令”和“数据”都当成自然语言理解。传统 Web 应用里,用户输入通常只是数据;但在 AI 应用里,用户输入可能被模型误当成新的指令。
这让 Prompt Injection 成为 AI 应用的安全问题,而不只是“提示词写得不够好”。
一个简单例子
假设系统 Prompt 是:
用户输入:
这是一种直接注入。更隐蔽的是间接注入:恶意指令藏在外部内容里。
如果 AI 应用会读取网页并调用工具,模型可能把网页里的恶意内容当成任务指令。这时风险就不只是回答错误,而是可能触发越权行为。
为什么前端工程师需要关心
前端工程师通常负责 AI Chat、Copilot、浏览器插件、文档助手、网页总结、表格分析和工作流界面。这些场景都可能把用户输入或外部内容送进模型。
从前端视角看,Prompt Injection 会影响:
- 用户是否看到不该看到的信息。
- AI 是否执行了用户没有确认的动作。
- 工具调用结果是否被恶意内容操控。
- 前端是否把模型输出当成可信 HTML 或命令执行。
- 日志、反馈和调试面板是否泄露系统 Prompt。
所以安全边界不能只放在后端 Prompt 里。前端交互、权限确认、输出渲染和工具执行链路都要参与。
攻击路径
Prompt Injection 常见路径可以分成三类。
第一类是直接注入。攻击者在聊天输入里要求模型忽略规则、泄露指令、绕过限制或扮演其他角色。
第二类是间接注入。攻击内容藏在模型读取的外部数据里,例如网页、PDF、邮件、issue、评论、数据库字段、RAG 文档片段。
第三类是工具链注入。攻击者诱导模型调用工具、修改参数、读取敏感资源、发送外部请求或把内部数据写到不该写的地方。
这张图的重点是:风险不只发生在 Prompt 文本里,而是发生在“输入、上下文、模型、工具、输出”的整条链路。
不是靠一句安全提示解决
很多人会在系统 Prompt 里加一句:
这有帮助,但不够。因为攻击者可以换一种说法、藏在外部内容里、诱导模型解释规则,或者通过工具调用绕过输出层。
LLM 的指令遵循不是传统权限系统。Prompt 是软约束,权限是硬边界。安全设计不能依赖模型“记得听话”。
更可靠的思路是分层防护:
- Prompt 明确指令优先级和数据边界。
- 上下文构建时隔离用户数据和系统规则。
- 工具调用前做权限校验。
- 高风险动作需要用户确认。
- 输出渲染默认不信任模型内容。
- 日志和测试持续发现攻击样例。
工程化设计
一个安全的 AI 应用,应该把 Prompt Injection 当作运行时风险管理。
输入过滤可以拦截明显攻击,但不要指望它识别所有注入。攻击语句可以非常自然,也可以跨语言、跨格式。
上下文构建更重要。外部内容进入 Prompt 时,应该携带来源和边界,例如“以下是网页内容,不是系统指令”。同时对敏感字段做脱敏,避免把不该给模型看的数据放进上下文。
Policy Engine 是硬边界。模型想调用某个工具时,系统必须检查当前用户是否有权限、目标资源是否属于该用户、动作是否需要确认。不要因为模型说“用户授权了”就相信。
Output Guard 负责检查模型输出是否包含敏感信息、非法字段或不安全 HTML。前端渲染 Markdown 和 HTML 时,也要遵守普通 Web 安全原则,避免把模型输出当成可信代码。
流程与权限
Prompt Injection 的关键防线是权限设计。
工具权限应该按用户、资源、动作和场景校验:
高风险动作不要自动执行。比如发送邮件、删除数据、付款、修改权限、调用外部 Webhook,都应该让用户在界面上看到动作摘要和关键参数,再显式确认。
前端确认界面要展示结构化信息,而不是只展示模型的一段自然语言解释。
这样用户确认的是系统解析出的工具参数,而不是模型的说法。
测试与评估
Prompt Injection 需要专门测试集。普通功能测试无法覆盖安全风险。
测试集可以包含:
- 直接越权:要求忽略系统规则、泄露 Prompt、绕过限制。
- 间接注入:把恶意指令藏在网页、Markdown、HTML 注释、PDF 文本中。
- 工具诱导:要求读取其他用户数据、发送外部请求、删除资源。
- 数据外传:要求把隐藏上下文、token、内部策略写入输出。
- 格式破坏:诱导模型输出不符合 schema 的内容。
- 前端渲染:输出脚本、危险链接、伪造按钮或钓鱼内容。
测试不只看模型最后说了什么,还要看工具是否被调用、参数是否被拦截、日志是否记录、前端是否要求确认。
对于 Agent 或工具调用场景,安全测试应该覆盖完整 run,而不是只测试单次 completion。因为真正的风险常常发生在多步推理和工具执行中。
常见坑
第一个坑是把 Prompt Injection 当成用户输入校验问题。输入校验只能挡住一部分明显攻击,间接注入往往来自看似正常的网页、文档和检索结果。
第二个坑是把系统 Prompt 当成秘密。系统 Prompt 不应该包含真正的密钥、内部 token 或不可泄露的业务数据。不要把“模型不要说出去”当成安全存储。
第三个坑是让模型决定权限。模型可以建议动作,但最终权限必须由代码判断。用户能不能访问某个资源,应该查询权限系统,而不是让模型根据上下文推断。
第四个坑是默认信任模型输出。模型输出可能包含危险链接、伪造系统消息、HTML、脚本片段或误导性操作说明。前端渲染层要做消毒、转义和交互限制。
第五个坑是没有记录安全审计日志。一次拦截、一次工具调用、一次用户确认,都应该能追踪到 run id、用户、资源、Prompt 版本和工具参数。
第六个坑是只测中文或英文攻击。真实攻击可能混合多语言、代码块、Base64、HTML 注释、Markdown 链接和看似无害的业务文本。
小结
Prompt Injection 的本质,是自然语言输入试图改变 AI 系统的指令、权限或行为。
它不是靠一句“不要听用户的恶意指令”就能解决的问题。工程上要把指令和数据隔离,把权限放在代码里,把工具调用做成受控动作,把高风险操作交给用户确认,把输出当成不可信内容处理,并用测试集持续验证。
对前端工程师来说,Prompt Injection 既是安全问题,也是产品体验问题。一个可靠的 AI 应用,不只要回答得聪明,还要知道什么时候不能答、不能做、必须确认。