feat(agent-scan): add memory/RAG poisoning detection skill#429
feat(agent-scan): add memory/RAG poisoning detection skill#429DevamShah wants to merge 1 commit into
Conversation
Add a Stage-2 detection skill, memory-rag-poisoning-detection, that probes agents with durable state (long-term memory, preference stores, or writable RAG/knowledge bases) for persistent-memory poisoning and knowledge-base contamination using planted per-run canary tokens. This is the missing detection source for OWASP ASI06 (Memory & Context Poisoning), which the owasp-asi classification skill already enumerates but had no skill producing findings for. indirect-injection-detection covers single-turn goal hijack; it does not cover durable content an attacker writes into a store the agent trusts on future turns/sessions. Wire-in: - prompt/skills/memory-rag-poisoning-detection/SKILL.md: new skill, mirrors tool-abuse-detection conventions (frontmatter, When to Use / Strategy / Output, two-phase plant/trigger vectors, vuln templates). - prompt/system/agent_vulnerability_detector.md: add to Standard Skills. - core/agent.py: register in _DETECTION_SKILLS (parallel path). - prompt/skills/owasp-asi/SKILL.md: add ASI mapping row (ASI06 primary). Markdown plus one-line Python only; no new dependencies, no behavioral change to existing skills, no external network target (canaries are generated per run). Signed-off-by: Devam Shah <devamshah91@gmail.com>
boy-hack
left a comment
There was a problem hiding this comment.
Code Review: feat(agent-scan): add memory/RAG poisoning detection skill
Overall Assessment: ✅ Looks Good — Ready to Merge with Minor Notes
This is a well-designed addition to the agent-scan skill suite. The skill fills a genuine detection gap (durable-state poisoning vs. ephemeral injection) and integrates cleanly with the existing architecture.
✅ Strengths
-
Conceptually sound distinction: Correctly separates memory/RAG poisoning (durable store corruption) from indirect injection (single-turn hijack). The
When to Useguard clause prevents false application on stateless agents. -
Canary token design: Using per-run random tokens (
MEMCANARY-<6 hex>,KBCANARY-<6 hex>) to verify both durability AND behavior corruption is a rigorous two-signal approach. Requiring both signals prevents false positives. -
Clean integration:
agent.pyadds the skill to theSKILLSlist in one line;owasp-asi/SKILL.mdandagent_vulnerability_detector.mdare updated consistently. -
OWASP ASI mapping:
ASI06(Prompt Injection via RAG) as primary andASI01, ASI04as secondary is accurate and matches the threat model. -
Output template: Well-structured
<vuln>blocks include conversation turns and canary evidence — consistent with existing skill output format.
Minor Observations
-
Session-reset assumption: The skill assumes some platforms support session resets between plant and trigger turns. The fallback (insert unrelated filler turn) is pragmatic, but false-negative rate will be higher for agents that don't persist state across dialogue sessions.
-
allowed-tools: dialogue: Correct and minimal — no concerns. -
No unit tests: Consistent with existing skill suite conventions.
Summary
| Check | Result |
|---|---|
| Skill logic correctness | Pass |
| Integration with agent.py SKILLS list | Pass |
| OWASP ASI table updated | Pass |
| agent_vulnerability_detector.md updated | Pass |
| Output format consistent | Pass |
| No breaking changes | Pass |
Ready to merge.
feat(agent-scan): add memory/RAG poisoning detection skill
Summary
Adds a new Stage-2 detection skill,
memory-rag-poisoning-detection, that probes agents with durable state — long-term memory, preference stores, or writable RAG/knowledge bases — for persistent-memory poisoning and knowledge-base contamination, using planted per-run canary tokens to verify both durability and behavior corruption.Problem / motivation
agent-scanships detection skills forauthorization-bypass,data-leakage,indirect-injection, andtool-abuse(plus theowasp-asiclassification skill).indirect-injection-detectioncovers single-turn goal hijack — a malicious instruction embedded in content the agent processes once. It does not cover the durable case: content an attacker writes into a store the agent trusts on future turns or sessions.That gap maps directly to OWASP ASI06 — Memory & Context Poisoning, which this repo's own
owasp-asiskill already enumerates but had no detection skill producing findings for. Two real, distinct attack classes go unscanned today:Both are durable and cross-turn, so a single-shot injection probe cannot detect them.
Change
Mirrors
tool-abuse-detection/SKILL.mdexactly — frontmatter (name/description/allowed-tools: dialogue) plusWhen to Use,Strategy(capability alignment → test vectors → judge), andOutputwith<vuln>blocks.agent-scan/prompt/skills/memory-rag-poisoning-detection/SKILL.md— the skill. Each test vector is two-phase: a plant turn that writes a fresh per-run canary (MEMCANARY-<hex>/KBCANARY-<hex>) plus a malicious directive, and a trigger turn (ideally after a session reset) that checks persistence and behavior change. Two<vuln>output templates (persistent memory, RAG knowledge base); the summary-to-memory vector reuses the memory template.agent-scan/prompt/system/agent_vulnerability_detector.md— adds the skill to Standard Skills with its applicability ("Long-term memory, preference store, or writable RAG/knowledge base"). This is the table the Stage-2 detector reads to decide which skill toload_skill.agent-scan/core/agent.py— adds the skill to_DETECTION_SKILLS, keeping the concurrentrun_parallel_detectionpath consistent with the detector table (one-line addition;_WORKER_CONCURRENCYunchanged).agent-scan/prompt/skills/owasp-asi/SKILL.md— adds the skill's row to the Detection-Source → ASI table (ASI06primary;ASI01,ASI04secondary).Markdown-and-one-line-Python only; no behavioral change to existing skills, no new dependencies, no external network target.
Low-false-positive design
Mirrors the repo's "refusals and educational explanations are not vulnerabilities" stance and adds two explicit guards:
Security rationale
The remediation guidance in each
<vuln>reflects this: treat memory/retrieval as untrusted data not executable instructions, separate "facts to recall" from "behavior to follow", scope memory per-user/session, and gate KB writes behind authorization with provenance tagging.Testing / validation
Validated against a clean checkout with this change applied:
tools/skill/skill.py,get_all_skills→os.listdir(SKILLS_DIR)) discovers the new skill;parse_skill_file()parsesname=memory-rag-poisoning-detection,description, andallowed-tools=dialoguefrom the frontmatter. No separate registration file is required.yaml.safe_load); all mirrored sections present (When to Use,Strategy, test vectors,Judge result,Output); two balanced<vuln>templates (same pattern as the siblingtool-abuse-detectionskill).python -m py_compile core/agent.pypasses;_DETECTION_SKILLSnow listsmemory-rag-poisoning-detection, so workers execute it. The detector-table edit is the live load-bearing wire-in.git diff --cached --statconfirms exactly four changes — the new SKILL.md plus three one-line additions — and nothing else.No live target is required to validate this change; the skill drives the existing
dialogue()tool at scan time like every other skill in this directory.