Source: Source pull request number: 878 in rohitg00/agentmemory (URL omitted to avoid GitHub cross-reference)
Title: Security: escape stored memory content in injected context (H1)
Author: DaveCole
State: open
Draft: no
Merged: no
Head: DaveCole/agentmemory:fix/h1-context-injection-escaping @ 328a13e
Base: main @ a76224f
Labels: (none)
Changed files: 0
Commits: 0
Created: 2026-06-09T21:02:26Z
Updated: 2026-06-09T21:09:02Z
Closed: (not closed)
Merged at: (not merged)
Original PR body:
Summary
mem::context wraps retrieved memories in <agentmemory-context>…</agentmemory-context> and prepends them to the agent's prompt, but interpolated every stored field raw. A memory containing </agentmemory-context><system>…</system> could close the wrapper early and inject instructions into future sessions — a takeover for anyone able to write a memory (REST/MCP client, or a poisoned file the agent read once and compressed into a narrative).
The codebase already had the right defense (escapeXml in enrich.ts); it just was not applied on the retrieval path.
Changes
- Promote
escapeXml into src/prompts/xml.ts as the single shared escaper.
- Escape every free-text field in
context.ts: profile concepts/files/conventions/commonErrors, lesson content/context, summary title/narrative/keyDecisions/filesModified, observation type/title/narrative, and the project= header attribute. Structural values (ids, timestamps, numbers) left as-is.
- Escape pinned-slot content in
slots.ts (label is already validated to ^[a-z][a-z0-9_]*$).
- Drop
enrich.ts's duplicate local escapeXml in favor of the shared one.
Tests
- New
test/context-injection-escaping.test.ts seeds a breakout payload into every vector and asserts the wrapper cannot be closed early and the payload survives only in neutralized (<…>) form.
- Updated one assertion in
test/context-lessons.test.ts (>5-file → >5-file).
- All touched tests pass (context/enrich/slots/xml).
🤖 Generated with Claude Code
Summary by CodeRabbit
-
Bug Fixes
- Enhanced security protections to prevent markup injection attacks through context memory fields, ensuring user-generated content is properly neutralized.
-
Tests
- Added comprehensive regression test suite to verify injection attack prevention across memory contexts.
Local branch:
Fork PR:
Fork decision:
Verification:
Notes:
Source: Source pull request number: 878 in rohitg00/agentmemory (URL omitted to avoid GitHub cross-reference)
Title: Security: escape stored memory content in injected context (H1)
Author: DaveCole
State: open
Draft: no
Merged: no
Head: DaveCole/agentmemory:fix/h1-context-injection-escaping @ 328a13e
Base: main @ a76224f
Labels: (none)
Changed files: 0
Commits: 0
Created: 2026-06-09T21:02:26Z
Updated: 2026-06-09T21:09:02Z
Closed: (not closed)
Merged at: (not merged)
Original PR body:
Summary
mem::contextwraps retrieved memories in<agentmemory-context>…</agentmemory-context>and prepends them to the agent's prompt, but interpolated every stored field raw. A memory containing</agentmemory-context><system>…</system>could close the wrapper early and inject instructions into future sessions — a takeover for anyone able to write a memory (REST/MCP client, or a poisoned file the agent read once and compressed into a narrative).The codebase already had the right defense (
escapeXmlinenrich.ts); it just was not applied on the retrieval path.Changes
escapeXmlintosrc/prompts/xml.tsas the single shared escaper.context.ts: profile concepts/files/conventions/commonErrors, lesson content/context, summary title/narrative/keyDecisions/filesModified, observation type/title/narrative, and theproject=header attribute. Structural values (ids, timestamps, numbers) left as-is.slots.ts(label is already validated to^[a-z][a-z0-9_]*$).enrich.ts's duplicate localescapeXmlin favor of the shared one.Tests
test/context-injection-escaping.test.tsseeds a breakout payload into every vector and asserts the wrapper cannot be closed early and the payload survives only in neutralized (<…>) form.test/context-lessons.test.ts(>5-file→>5-file).🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
Local branch:
Fork PR:
Fork decision:
Verification:
Notes: