T02 · Agent Memory Poisoning
- Location
scripts/safe-memory-write.sh:20- Finding
Unscanned source metadata can poison persistent agent memory
- Content
View full analysis
> "$OUTFILE" echo "{\"status\":\"accepted\",\"severity\":\"$SEVERITY\",\"score\":$SCORE,\"written_to\":\"$OUTFILE\"}" ``` ### Technical Analysis The script scans and sanitizes only the value stored in `TEXT`. The caller-controlled `SOURCE` value is neither validated nor passed through `scan-content.py`, but is interpolated directly into a record written to daily memory or `MEMORY.md`. Shell quoting prevents shell command injection at this sink, but it does not prevent embedded newlines, Markdown, prompt-injection phrases, or forged memory entries from being persisted. Consequently, malicious instructions placed in `SOURCE` bypass the advertised scan-before-write control. The documented source values form a small fixed set, but the implementation does not enforce that allowlist. ### Attack Path 1. An attacker gains influence over arguments passed to `safe-memory-write.sh`, directly or through a tool that constructs the invocation from external metadata. 2. The attacker supplies benign text through `--text` so that the scanner reports a severity below the quarantine threshold. 3. The attacker places multiline instructions or forged memory records in `--source`. 4. The attacker selects `--target longterm`, or relies on the default d ...[truncated 985 chars]- Remediation
View remediation
&2 exit 2 ;; esac ``` 2. Reject control characters, including carriage returns and newlines, in all metadata fields. 3. Scan every caller-controlled field that will be persisted, not only `TEXT`. 4. Store records in a structured format such as JSON Lines and serialize values using a real JSON encoder instead of interpolating them into Markdown. 5. If Markdown storage is required, escape Markdown syntax and convert metadata to a canonical single-line representation. 6. Add regression tests using multiline source labels, prompt-injection phrases, Markdown headings, and forged list entries. ]]>
