← 返回 2026-06-11

POISE:面向LLM代理的位置感知不可检测技能注入攻击 POISE: Position-Aware Undetectable Skill Injection on LLM Agents

Haochang Hao, Dehai Min, Zhifang Zhang, Yunbei Zhang, Miao Xu, Yingqiang Ge, Lu Cheng 📅 2026-06-06 👍 4 2026-07-13 08:37
代理攻击 供应链安全 大语言模型安全 技能注入 提示词注入

提出POISE攻击,通过在技能文件主体中精准注入单行命令实现隐蔽高效的LLM代理投毒

前置知识

LLM代理(LLM Agent)

LLM代理是基于大语言模型的自主智能体,能够通过推理工具调用、代码执行、文件操作和外部应用交互来完成多步骤任务。代理通过系统提示词获得工具定义,通过任务提示词接收用户指令,通过工具调用与外部环境交互,形成推理-行动循环。生产级编码代理(如OpenAI Codex CLI、Claude Code)暴露文件系统和shell接口,使代理能够执行任意bash命令,这是其强大能力但也引入了严重安全风险的根本原因。

本文研究的目标就是利用代理自动执行技能中命令的特性,在用户执行合法任务的同时触发攻击者选定的恶意行为,理解代理如何读取和执行技能内容是理解攻击机制的基础。

技能文件(Agent Skills)

技能文件是LLM代理用于快速适应特定领域的轻量级扩展机制,通常由SKILL.md文档和可选的辅助脚本组成。SKILL.md是结构化Markdown文件,包含YAML frontmatter(元数据如name、description)和主体内容(编号程序、安装步骤等)。技能通过公共市场、社区仓库或组织模板共享,用户安装技能后,代理在执行相关任务时会读取并遵循技能中的自然语言指令和脚本调用,从而获得特定领域的专业能力,无需在每次提示中重复说明任务细节。

技能的开放性和可移植性使其成为完美的供应链攻击载体,攻击者只需投毒一个技能文件,就能在未来无数次会话中重用该恶意技能,这是POISE攻击能够高效运作的前提条件。

提示词注入(Prompt Injection)

提示词注入是一种对抗性攻击技术,通过向LLM的输入中注入恶意指令来操纵模型行为。直接提示词注入直接在用户提示中插入恶意指令,间接提示词注入则通过检索内容、工具描述、内存、MCP服务器元数据等第三方载体间接影响模型。在代理场景下,技能文件就是新的注入载体:代理将技能内容视为任务相关的权威指令并自动执行其中的命令,攻击者通过在技能中植入恶意指令就能使代理在用户不知情的情况下执行任意操作。

POISE本质上是一种针对技能文件载体的间接提示词注入攻击,它与传统的文档处理或工具描述注入不同,利用的是技能机制中代理对自然语言指令的信任,这是理解攻击向量分类和防御设计的关键。

攻击成功率(Attack Success Rate, ASR)

ASR是本文提出的核心评估指标,定义为在至少一次试验中既触发攻击者payload(canary标记执行)又通过任务验证器的(task, harm)变体比例。ASR比单纯的触发率更严格,因为如果攻击执行导致用户任务失败,用户会收到明确的失败信号并检查技能文件。ASR测量的是隐藏性攻击的成功:攻击者选定的命令执行,同时用户的合法任务仍然完成,这是操作意义上最有价值的指标。试验采用OR聚合:如果两次试验中任意一次满足条件则计为成功。

ASR反映了真实世界中攻击的有效性,攻击不仅要被执行,还要不引起用户怀疑,这是POISE相比其他方法在可靠性-隐身性权衡上的核心优势所在。

研究动机

现有的技能投毒攻击方法面临可靠性-隐身性的根本权衡。一种有效策略是投毒YAML header,特别是description字段,因为这个元数据在任务开始前就被加载到代理上下文中。然而,由于简短的header位于文件顶部且旨在总结技能,直接注入恶意命令很容易被人工审核者或静态扫描器发现。另一种选择是将恶意命令注入技能主体,通常是将恶意子步骤分散到现有程序中。但这种模式存在更关键的问题:代理会对其阅读的技能内容进行推理,并将不符合当前任务的上下文外命令标记为可疑并跳过。因此,分散的主体注入不可靠:每个可见的恶意步骤都是代理将技能标记为与其声明目的不一致的另一个机会。在Skill-Inject基准上,随机放置的主体注入基线B@k=2的触发率仅为62.7%,而POISE达到90.7%,差距达28个百分点。

本文的目标是本文的具体目标是设计一种技能投毒攻击,在保持高隐身性的同时实现高可靠性。攻击必须满足三个核心要求:第一,攻击者选定的命令必须执行(触发canary标记);第二,用户的合法任务必须通过验证器(不产生失败信号);第三,注入内容必须在静态检测、用户任务信号和代理轨迹三个维度上保持不可检测。作者通过定义Attack Success Rate (ASR)作为严格指标来量化这一目标:ASR要求在单次试验中同时满足payload执行和任务通过,这是操作意义上最有价值的成功度量。

与已有工作不同的是,本文的独特切入角度是认识到单行脚本间接注入可以同时解决可靠性和隐身性问题。与分散多个恶意子步骤的攻击不同,POISE将所有恶意行为打包到一个小型辅助脚本中,技能本身只需包含一行bash调用。代理会推理SKILL.md文本但通常不会打开它被要求执行的脚本主体,因此每个可疑操作都距离代理一步之遥且位于代理视为不透明依赖的文件中。与直接在YAML描述中注入命令不同,POISE将单行注入限制在主体位置,该位置自然支持额外的指令,如编号程序或setup/install部分。这种位置感知放置结合上下文感知重写,使触发器匹配周围文本并框架化为常规前提条件,从而实现了28.0个百分点ASR提升(相对于随机基线)和仅5.6%新高风险警报率(相对于清洁基线)。

核心方法

POISE(Position-aware Operations via Injected Skill Execution)是一种位置感知的技能文件注入攻击,其核心思路是将攻击者选定的行为打包到自包含的辅助脚本中,使投毒技能只需包含一行触发该脚本的命令。这种方法避免了分散主体注入的脆弱性,因为每个可见的恶意步骤都是代理将技能标记为与任务不一致的另一个机会。为了保持隐身性,POISE结合了位置感知放置和上下文重写:首先将放置限制到主体中可行位置,这些位置的局部结构已经支持额外指令;然后使用上下文感知生成器使触发器匹配周围散文并将其框架化为常规前提条件。技术路线上,POISE定义了三个自然注入位置:YAML description append、numbered-step insert和install-section append,并优先选择主体位置(后两者)因为它们自然支持shell命令的本地习惯。攻击构造分三步:选择可行主体位置、编写注入行、合并到技能中。

POISE的核心创新点在于认识到单行脚本间接注入可以同时解决现有方法的可靠性和隐身性权衡。与YAML header注入相比,主体位置注入将shell命令放置在自然支持命令的区域(如编号程序或安装步骤),避免了静态扫描器对元数据字段中可执行内容的敏感性。与分散主体注入相比,单行调用将所有恶意操作封装到辅助脚本中,代理会执行调用但不会检查脚本主体,因此每个可疑操作都距离代理推理一步之遥。这种脚本间接隐藏了危害:代理推理SKILL.md文本,但通常不会打开它被要求执行的脚本主体,因此每个可疑操作都位于代理视为不透明依赖的文件中。实验验证了这一点:K=1在Skill-Inject上触发91到97%变体,在SkillsBench上触发80到96%变体。

方法步骤详情

POISE攻击构造分为三个步骤。第一步:选择一个可行主体位置。系统根据结构规则枚举技能的可行主体位置(排除YAML类型)并均匀随机选择一个。选择不是优化关键:每个主体位置类型在首次尝试时的触发率都超过70%,所以任何可行主体位置都有效。第二步:编写注入行。单独的生成器LLM编写注入文本:简短的、域适当的段落,将canary命令框架化为常规前提条件(如首次使用前运行验证环境)。生成器接收技能大纲、局部上下文和类型特定的强化器风格;明确导向命令式、时间锚定的措辞并避免模糊语言。第三步:合并。生成的文本插入选定行,必要时重新编号步骤。这是唯一修改;投毒技能的其他内容与清洁原始文件逐字节相同。主要实验使用K=1:一个选定位置、一行生成文本。更大的K不需要,因为K=1已经超过随机双位置基线B@k=2。

技术新颖性

POISE的技术新颖性体现在三个方面:第一,位置感知的注入位置目录,系统性地识别SKILL.md中自然支持额外指令的结构位置(编号程序、安装步骤),避免了随机注入导致的高怀疑度;第二,上下文感知的生成重写,使用单独的LLM根据局部上下文生成与周围散文风格一致的触发文本,将恶意调用框架化为常规前提条件;第三,单行脚本间接注入,将所有恶意行为封装到辅助脚本中,避免在技能主体中暴露多个可见的恶意步骤。实验表明,这种设计在保持隐身性(仅5.6%新高风险警报)的同时实现了显著更高的可靠性(89.3% ASR vs 61.3%随机基线),并且在四种代理配置上具有强泛化能力(90.7到97.3%触发率)。

Overview of POISE
Figure 1: Overview of POISE

实验结果

核心发现包括三个实验。首先,在Skill-Inject基准上,单行POISE主体注入实现89.3% ASR,比随机放置基线B@k=2(61.3%)高28.0个百分点,比YAML-only基线(86.7%)高2.6个百分点。验证器通过率(97.3%)保持接近清洁基线(96.0%)。触发组件跨伤害类别泛化(exfil 23/25、cfg 23/25、sys 22/25)。其次,在SkillsBench基准上,POISE触发86.4%的n=81变体并实现16.0% ASR;绝对ASR较低是因为清洁验证器天花板较低(25.9%),但POISE保留该天花板同时优于YAML-only(11.1%)和B@k=2(9.9%)。第三,跨代理传输实验显示,同一POISE主体注入在四种代理配置上以90.7到97.3%触发率触发,包括最抗注入的Claude Code(两个基准上86.5%聚合触发率)。验证器通过率保持高位(90.7到97.3%),因此ASR保持在86.7到90.7%。

Main attack results (%)
Table 1: Main attack results (%)
SkillsBench task audit
Table 2: SkillsBench task audit
Dead-fraction of the SKILL.md body
Table 3: Dead-fraction of the SKILL.md body
Verifier pass rate (codex加gpt-5.2) under Clean, POISE, and 加distrust
Table 4: Verifier pass rate (codex加gpt-5.2) under Clean, POISE, and 加distrust
Resource budget
Table 5: Resource budget
POISE is both stealthy and reliable
Figure 2: POISE is both stealthy and reliable
查看结构化数据
任务指标本文基线提升
Skill-Inject文档处理 Attack Success Rate (ASR) 89.3% 61.3% (B@k=2随机放置) +28.0个百分点
Skill-Inject文档处理 Trigger Rate 90.7% 62.7% (B@k=2随机放置) +28.0个百分点
Skill-Inject文档处理 Verifier Pass Rate 97.3% 96.0% (清洁基线) +1.3个百分点
SkillsBench多域任务 Attack Success Rate (ASR) 16.0% 9.9% (B@k=2随机放置) +6.1个百分点
SkillsBench多域任务 Trigger Rate 86.4% 55.6% (B@k=2随机放置) +30.8个百分点
跨代理传输 (4种配置) Trigger Rate 90.7到97.3% N/A 强泛化能力

局限与改进

局限性分析包括作者承认的和我们自己的观察。作者承认的局限性:第一,基准范围适中,Skill-Inject和SkillsBench子集分别为25和27任务乘以3伤害类别,从代理技能基准而非公共市场抽取,因此真实世界技能生态系统的攻击率(规模、广度、技能质量分布)是推断而非测量的。第二,单一攻击家族,实例化为一个注入行调用一个自包含脚本,3.2论证这是给定代理消费技能文件方式的最可靠形状,但未消融分散多步攻击、完全在技能散文内的payload或组合多注入行的攻击。第三,模型选择,注入文本生成器使用deepseek-v4-pro(T=0.7),未消融此模型;5.2中每种位置类型的强触发率表明位置目录承载大部分结果。我们的观察:第一,Canary代理测量的是攻击者提供的命令是否执行,而不是任意payload的下游真实世界影响。第二,检测和拒绝范围,静态检测使用一个扫描器框架和四个LLM judge评估,其他检测器设计(如跟随脚本调用到其磁盘主体的数据流分析器或在标记技能注入语料库上微调的分类器)可能表现不同。第三,代理覆盖,跨代理传输实验涵盖四种代理加模型组合,其他harness(Cursor、Aider、Goose、OpenHands等)和其他模型backbone可能在技能加载机制或拒绝姿态上不同。

独立分析的弱点

独立分析的弱点包括三个具体场景。第一,对imperative reinforcer的依赖:Appendix H的自适应攻击者实验表明,如果去除注入散文中的每个imperative reinforcer,攻击成功降至0/75,即使没有应用任何防御。这表明攻击的关键成功因素是代理将命令视为绑定而非说明的措辞选择,如果未来的代理harness学会怀疑这种强化器式语言,攻击可能大幅削弱。改进方向:研究不依赖强imperative框架的替代表述,例如使用更软的前提条件语言或利用代理的其他认知偏差。第二,对脚本路径的信任:Claude Code在4/75 Skill-Inject变体上因脚本路径不匹配而拒绝,这表明如果harness要求技能脚本必须位于技能目录内而非第三方路径,攻击成功率可能降低。改进方向:探索将辅助脚本隐藏在技能自身目录结构中的方法,或使用路径混淆技术。第三,对单行注入的假设:未测试分散多步攻击或完全在技能散文内的payload,这些变体可能在某些场景下更有效或更难检测。改进方向:研究多行注入策略和内联payload技术,评估它们在不同代理配置上的表现。

未来方向

未来研究方向包括作者提出的和基于成果可延伸的。作者提出的:第一,测试90到97%触发范围是否特定于单行形状,还是更广泛地适用于imperative框架的技能内容;第二,研究其他harness和其他模型backbone的技能加载机制或拒绝姿态,特别是随着代理供应商修补我们识别的负载信任gate;第三,扩展到真实的公共市场技能生态系统(规模、广度、技能质量分布)。基于成果可延伸的:第一,研究更复杂的payload,不仅限于单行脚本调用,包括多步攻击、完全在技能散文内的payload或组合多注入行的攻击;第二,设计更智能的静态检测器,如跟随脚本调用到其磁盘主体的数据流分析器或在标记技能注入语料库上微调的分类器;第三,研究更精细的防御策略,如仅在技能指向外部脚本路径时应用不信任前言,以在保持攻击抑制的同时减少SkillsBench上的效用损失;第四,探索技能协议级别的结构性修复,如显式标记imperative内容使harness级别过滤器可以区分follow和consult。

复现评估

复现评估显示项目的开源程度良好。代码和artifacts包括pipeline、canary脚本、评估harness和投毒技能发布,在https://github.com/liofoil/SkillSafety可用。实验基础设施使用Daytona提供的隔离一次性Docker沙箱,每个试验从任务的Dockerfile构建新沙箱并叠加上我们的ijplan payload目录布局(canary脚本加上honey标记的workspace)。代理harness是Harbor,编排沙箱生命周期、代理启动、工具调用和验证器调用。每试验资源上限为4 CPU核心、8 GB RAM、10 GB磁盘和600秒任务级timeout_sec。运行成本方面,整个24-cell矩阵(Primary POISE、跨代理传输、基线、清洁基线、防御、自适应攻击者)共2467试验,成本525到1045美元。资源预算详细表格显示每个phase的试验数和成本范围,codex和claude-code试验成本约为openclaw-flash试验的10倍。Wallclock方面,使用max-workers 80在单个Daytona配额上,典型的75或81变体cell在codex/openclaw上2到4小时完成,在claude-code加claude-sonnet-4-6上4到7小时完成。整体复现难度中等,需要理解Docker、代理harness和技能机制,但提供了详细的pin版本和复现说明。