T02 · Agent Memory Poisoning
- Location
- scripts/compress_session.py:181
- Finding
- Persistent Prompt Injection Through AI-Generated Session Summaries<![CDATA[ ## Vulnerability Details **File Location**: `scripts/compress_session.py:181-199`, `scripts/compress_session.py:220-226`, `scripts/compress_session.py:309-312`, and `SKILL.md:49-53` **Vulnerability Type**: Persistent prompt injection and memory poisoning **Risk Level**: High ### Vulnerable Code ```python prompt = f"""将以下会话内容压缩到{config['max_chars']}字以内。 压缩要求: 1. 保留:关键配置、路径、已验证方案、错误教训、重要决策 2. 删除:过程描述、重复信息、调试输出、格式说明、冗余解释 3. 输出纯Markdown格式,不加任何额外解释 压缩示例: 原文:用户询问了股票投资的问题,我详细解释了K线图的使用方法,包括阳线、阴线、十字星等形态,还讲解了均线系统的5日、10日、20日、60日均线的作用,以及MACD指标的金叉死叉信号... 压缩:技术分析要点:K线看趋势(阳线涨/阴线跌/十字星变盘),均线判支撑压力(5/10/20/60日),MACD看金叉死叉。 原文:部署过程中遇到了依赖问题,先尝试了pip install但是报错,然后检查了Python版本发现是3.8,需要升级到3.10,升级后重新安装依赖,最终成功启动服务... 压缩:部署要点:需Python 3.10+,pip install依赖,服务已启动。教训:先检查Python版本。 --- 待压缩内容: {text}""" ``` ```python response = client.chat.completions.create( model=config['model'], messages=[{'role': 'user', 'content': prompt}], max_tokens=config['max_tokens'], timeout=timeout ) return response.choices[0].message.content ``` ```python today = datetime.now().strftime('%Y-%m-%d %H:%M') with open(latest_file, 'w', encoding='utf-8') as f: f.write(f'# 会话摘要(压缩版)更新于 {today}\n\n{compressed}') ``` The Skill then requires this generated file to be loaded in later sessions: ```text ① INDEX.md ② latest-summary.md ③ Task-specific memory ④ Last five conversation rounds ``` ### Technical Analysis The compressor interpolates untrusted conversation or file content directly into an instruction prompt. There is no strict separation between the compressor's instructions and the supplied content, so embedded directives can be interpreted as instructions by the summarization model. The returned model output is accepted without schema validation, instruction filtering, provenance labeling, or human confirmation. It is then written to the persistent global memory file `~/.openclaw/memory/sessions/latest-summary.md`. The Skill documentation directs future Agent sessions to load th ...[truncated 1662 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat all source conversation content as untrusted data and clearly delimit it using a structured message or serialization format. 2. Use separate system and user messages, with the system message explicitly prohibiting execution or preservation of instructions found inside the source material. 3. Require the model to return a strict structured schema containing only approved factual fields. 4. Validate generated output before persistence. Reject or quarantine content containing imperative instructions, role changes, tool directives, hidden markup, or attempts to override higher-priority instructions. 5. Mark summaries as untrusted reference data and instruct consuming Agents never to treat them as executable instructions. 6. Require user review or explicit confirmation before replacing persistent cross-session memory. 7. Preserve provenance metadata so future Agents can distinguish user statements, model-generated summaries, and trusted configuration. 8. Add adversarial tests covering prompt injection, indirect prompt injection, encoded instructions, and directives disguised as configuration or decisions. ]]>
