T02 · Agent Memory Poisoning
- Location
config/patterns.json:81- Finding
Untrusted Conversation Text Can Become Persistent, Always-Active Agent Instructions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This memory skill has a coherent purpose, but it needs Review because it stores and reuses conversations persistently with weak scoping, can promote ordinary text into always-active rules, and can send memory data to an external or configurable endpoint.
Review before installing. Use LIGHT-only mode unless you are comfortable with persistent cross-session memory and external processing of daily logs; avoid shared or group contexts until isolation is enforced; do not point api.base_url at another endpoint while using ANTHROPIC_API_KEY; avoid --force uninstall; and inspect or back up memory data before enabling cron or deletion paths.
config/patterns.json:81Untrusted Conversation Text Can Become Persistent, Always-Active Agent Instructions
scripts/reflect.py:143LLM Responses Can Autonomously Rewrite and Poison Persistent Memory
scripts/consolidate.py:36Unredacted Daily Logs and Persistent Memory Are Sent to an External LLM
scripts/consolidate.py:55Configurable API Endpoint Receives the Anthropic API Key
scripts/recall.py:303Private Memory Is Recalled Without User, Session, or Group-Context Isolation
install.sh:76Custom Workspace and Installation Paths Permit Python or Cron Command Injection
uninstall.sh:79Uninstaller Can Remove Unrelated User Cron Entries
scripts/maintenance.py:88Configuration-Key Mismatch Aborts the Nightly Maintenance Pipeline
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
)
try:
with urllib.request.urlopen(req, timeout=SETTINGS["api"]["timeout_seconds"]) as resp:
data = json.loads(resp.read().decode("utf-8"))
text = ""
for block in data.get("content", []):
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
)
try:
with urllib.request.urlopen(req, timeout=SETTINGS["api"]["timeout_seconds"]) as resp:
data = json.loads(resp.read().decode("utf-8"))
text = ""
for block in data.get("content", []):
The skill is presented as a memory utility, but the documented uninstall/rollback behavior includes crontab modification, database/workspace deletion, and restoration of MEMORY.md. That functional breadth increases risk because users or agents may invoke a seemingly simple memory skill without appreciating that it can alter scheduled tasks and remove local state.
The skill is presented as a memory utility, but the documented uninstall/rollback behavior includes crontab modification, database/workspace deletion, and restoration of MEMORY.md. That functional breadth increases risk because users or agents may invoke a seemingly simple memory skill without appreciating that it can alter scheduled tasks and remove local state.
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
# 5. Clean up ancillary files
for F in "${WORKSPACE}/memory-oracle-pending.json"; do
[[ -f "$F" ]] && rm -f "$F" && info " Removed: $F"
done
# Clean reflection files
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
# 5. Clean up ancillary files
for F in "${WORKSPACE}/memory-oracle-pending.json"; do
[[ -f "$F" ]] && rm -f "$F" && info " Removed: $F"
done
# Clean reflection files
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
# 5. Clean up ancillary files
for F in "${WORKSPACE}/memory-oracle-pending.json"; do
[[ -f "$F" ]] && rm -f "$F" && info " Removed: $F"
done
# Clean reflection files
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
info ""
info "Manual steps remaining:"
info " 1. Remove the Memory Oracle Protocol section from your AGENTS.md"
info " 2. Remove the checkpoint.py reference from your compaction config"
info " 3. Optionally: rm -rf $SCRIPT_DIR (remove skill files)"
info ""
if [[ -f "${WORKSPACE}/memory-oracle-export-"* ]] 2>/dev/null; then
The skill documents substantial capabilities—filesystem reads/writes, environment-variable access, cron manipulation, and optional network calls—without any explicit tool/permission scope. In an agent ecosystem, missing scope declarations weaken reviewability and can let a broadly-triggered memory skill execute higher-impact operations than a user would reasonably expect.
The trigger phrases are very broad ('memory', 'remember', 'recall', 'guardrails', 'pick up where we left off'), making accidental invocation likely in ordinary conversation. Because the skill stores and retrieves persistent context, unintended activation can cause over-collection, unnecessary retention, or disclosure of prior-session information in contexts where the user did not explicitly ask for persistence.
The skill is explicitly designed to preserve facts across sessions and to answer 'what do you know about X' from stored memory. In a memory skill this is contextually expected, but without strong consent boundaries and scoping it still creates a real risk of retaining and later disclosing personal or sensitive information beyond the user's intent.
The protocol instructs the agent to persist the full conversation turn after every response and to feed user queries into recall processing. That creates a strong data-retention pathway for potentially sensitive user content, and the same memory may later be surfaced or transmitted to HEAVY reflection/consolidation flows, increasing privacy and confidentiality risk across sessions.
The documented use of '--force' to skip confirmations for uninstall operations is risky because the same uninstall flow includes cron removal, cleanup of files, optional database deletion, and restoration actions. In agent-driven environments, non-interactive destructive modes can be triggered without adequate human review, increasing the chance of accidental data loss or system modification.
5. Clean up reflection files and pending queue
6. Print remaining manual steps (AGENTS.md cleanup, compaction config)
Use `--force` to skip confirmations, `--keep-db` to keep the database while removing everything else.
## Known issues & limitations
The documentation first says that if the API key is not set, the HEAVY process is skipped entirely, but immediately afterward says users can point api.model to a local model endpoint instead. Those statements cannot both be universally true, so the docs actively contradict the described behavior and deployment options.
Suspicious Unicode normalization or mixed-script content
The file defines parallel patterns_en and patterns_ru matchers throughout the configuration, indicating the skill is designed to operate only for English and Russian inputs. Because no natural-language text in this file offers user opt-in or explains a justified region-specific limitation, this creates a locale policy concern under the language/locale rule.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"api": {
"model": "claude-sonnet-4-20250514",
"max_tokens": 1000,
"base_url": "https://api.anthropic.com/v1/messages",
"timeout_seconds": 30
},
"cron": {
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
error "FTS5 is required for full-text search."
error ""
error "How to fix:"
error " Ubuntu/Debian: sudo apt install libsqlite3-dev && rebuild Python"
error " Alpine: apk add sqlite-dev"
error " macOS: brew install sqlite3 (FTS5 included by default)"
error " Or use pyenv: PYTHON_CONFIGURE_OPTS='--enable-loadable-sqlite-extensions' pyenv install 3.12"
When --workspace is provided, the script silently updates config/settings.json in place, changing multiple path settings. Although it logs the custom workspace, it does not clearly disclose that a tracked configuration file will be modified before performing the write.
The installer offers to add a persistent nightly cron job that will continue executing the skill's Python scripts across sessions. In the context of a memory skill that processes stored conversational data and may use an API key, persistence increases risk by enabling ongoing unattended access to user data and repeated execution long after the original install decision.
CRON_CMD_NIGHTLY="0 3 * * * cd $SCRIPT_DIR && ANTHROPIC_API_KEY=\${ANTHROPIC_API_KEY} $PYTHON scripts/consolidate.py && $PYTHON scripts/reflect.py --auto && $PYTHON scripts/maintenance.py >> /tmp/memory-oracle-cron.log 2>&1"
# Check if already installed
EXISTING=$(crontab -l 2>/dev/null | grep -c "memory-oracle" || true)
if [[ "$EXISTING" -gt 0 ]]; then
warn "Cron jobs already exist. Skipping. To reinstall, remove them first:"
warn " crontab -e # then remove memory-oracle lines"
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
EXISTING=$(crontab -l 2>/dev/null | grep -c "memory-oracle" || true)
if [[ "$EXISTING" -gt 0 ]]; then
warn "Cron jobs already exist. Skipping. To reinstall, remove them first:"
warn " crontab -e # then remove memory-oracle lines"
else
(crontab -l 2>/dev/null || true; echo "# memory-oracle nightly pipeline"; echo "$CRON_CMD_NIGHTLY") | crontab -
info "Cron installed: nightly at 03:00"
This command actually installs a cron entry into the user's crontab, establishing durable background execution. Within this skill's context, that is more security-relevant than ordinary automation because the scheduled jobs process persistent memory, may invoke LLM-backed reflection using ANTHROPIC_API_KEY, and write logs to /tmp, increasing exposure if the behavior is not fully understood by the user.
warn "Cron jobs already exist. Skipping. To reinstall, remove them first:"
warn " crontab -e # then remove memory-oracle lines"
else
(crontab -l 2>/dev/null || true; echo "# memory-oracle nightly pipeline"; echo "$CRON_CMD_NIGHTLY") | crontab -
info "Cron installed: nightly at 03:00"
fi
else
The printed AGENTS.md snippet instructs activation based on the exact English phrases "remember this" or "this is critical." This hard-codes an English-only interaction pattern without user opt-in or any documented locale flexibility.
The prompt instructs the model to write the strategic summary in the user's primary language at L58 and repeats the requirement at L69. This imposes a language behavior without indicating that the user selected or consented to that locale choice, which matches the language/locale policy violation criteria.
The prompt instructs the model to write the daily summary in the language it infers the user primarily uses, without requiring an explicit user preference or current-session consent. In a persistent memory system, this can cause unexpected disclosure, misclassification of language preference, or generation of summaries in a language unsuitable for downstream reviewers or safety workflows.
No suspicious patterns detected.