← 中文资源

简体中文版本

提示注入

提示注入把指令隐藏在不可信内容中使模型听命于攻击者,仅靠提示无法彻底解决,需要纵深防御与最小权限。

阅读英文原文

概念概述

提示注入(Prompt Injection)指的是:提示注入把指令隐藏在不可信内容中使模型听命于攻击者,仅靠提示无法彻底解决,需要纵深防御与最小权限。

从更严格的定义看,Prompt injection is an attack in which adversarial text, often placed in retrieved documents or user content, causes a language model to disregard its original instructions or leak information. 该概念在工程实践中的价值,在于它能帮助团队用统一的语言描述一个具体的质量属性或设计约束,从而在评审与协作中减少歧义。

为什么需要它

It affects any application that lets a model read content the developer does not control, including chat, summarisation, and retrieval-augmented generation. 它与 Semantic Caching、Document Chunking Strategies、AI Guardrails and Output Validation 等概念经常一起出现,用于解决相近的工程问题。理解它的适用场景,有助于在多种备选方案之间做出有依据的取舍,而不是凭直觉选择技术方案。

常见误解

  • a strong system prompt prevents injection
  • injection only matters for chatbots that act on instructions

需要避免的反模式

  • concatenating retrieved text into the same turn as system instructions
  • granting a model tools without limiting their effects

实践要点

  1. Because the model treats all text in the window as potential instructions, content with no trusted provenance can hijack behaviour, and there is no reliable text-only filter.
  2. Defence in depth applies: separate trusted instructions from untrusted data, constrain the actions a model can take, and validate outputs before acting.
  3. Any tool the model can call is a real capability, so least privilege and human confirmation for consequential actions limit the blast radius.

参考来源

https://owasp.org/www-project-top-10-for-large-language-model-applications/

代码示例

-- 危险示范:拼接用户输入(永远不要这样做)
-- SELECT * FROM products WHERE name = '克" OR "1"="1'
-- ORDER BY 攻击同理:排序字段直接内插

-- 安全形态:值全部走绑定参数
SELECT id, name, price_cents
FROM products
WHERE category = $1
  AND price_cents BETWEEN $2 AND $3
ORDER BY price_cents
LIMIT $4;
-- 绑定:$1='electronics', $2=1000, $3=5000, $4=20

-- IN 列表的动态占位符:结构生成、值绑定
SELECT id, name
FROM products
WHERE id IN ($1, $2, $3);
-- 占位符数量由应用层数组长度生成,值逐个绑定

-- ORDER BY 无法参数化:白名单映射是唯一出路
-- 应用层伪代码:
--   allowed = { 'price': 'price_cents',
--               'name': 'name',
--               'created': 'created_at DESC' }
--   order_sql = allowed[user_input] or fail()
SELECT id, name, price_cents
FROM products
WHERE category = $1
ORDER BY price_cents DESC NULLS LAST;  -- order_sql 来自白名单

-- 标识符必须动态时用格式化函数加引号
SELECT quote_ident('user_input_column');  -- 带引号的安全标识符
const ENTITIES = {
  "&": "&",
  "<": "&lt;",
  ">": "&gt;",
  '"': "&quot;",
  "'": "&#39;",
};

export function escapeHtml(text) {
  if (text === null || text === undefined) return "";
  return String(text).replace(/[&<>"']/g, (char) => ENTITIES[char]);
}