Back to skill

Security audit

Working Memory Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill has a legitimate memory-management purpose, but it needs review because it can persist private session data, change future agent instructions, and includes unsafe local-file/context-loading behavior.

Review before installing or using. Run migration with --dry-run first, consider --skip-agent-patch, keep memory files private and out of shared repositories, and treat all generated memory as sensitive. Do not place loaded memory directly into a system prompt without an explicit rule that it is untrusted historical data. The loader should be fixed to restrict lookups to canonical memory/YYYY-MM-DD.md files before use in hostile or shared environments.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T02 · Agent Memory Poisoning

Error
Location
SKILL.md:120
Finding

Persistent Prompt Injection Through Untrusted Working-Memory Content

Content
View full analysis
{context.text} {your_existing_system_prompt} """ ``` ```python # scripts/loader.py:72-79 @property def text(self) -> str: """Concatenate all loaded content into a single memory block.""" parts = [] for c in self.contents: parts.append(f"\n{c.text}") return "\n\n---\n\n".join(parts) ``` ```python # scripts/writer.py:147-198 def _write_daily_log( self, today: str, now: datetime, duration: int, summary: str, events: Optional[str], mood: str, ): """Write or append to today's daily log.""" memory_dir = self.root / "memory" memory_dir.mkdir(parents=True, exist_ok=True) log_path = memory_dir / f"{today}.md" threads_str = ", ".join(self.capture.thread_refs) if self.capture.thread_refs else "—" sections = [] if not log_path.exists(): sections.append(f"# Daily Log — {today}\n") sections.append( f"> Session: {now.strftime('%H:%M')} UTC, ~{duration} min\n" f"> Thread(s) active: {threads_str}\n" ) sections.append(f"## Session Summary\n\n{summary}\n") if events: sections.append(f"## What Happened\n\n{events}\n") if self.capture.decisions: rows = ["| Decision | Reasoning | Ref |", "|----------|-----------|-----|"] for d in self.capture.decisions: ref = ", ".join(self.capture.thread_refs) if self.capture.thread_refs else "—" ...[truncated 3006 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/loader.py:104
Finding

Arbitrary Local File Read Through Unrestricted Targeted Lookup Path

Content
View full analysis
str: full = self.root / relative_path if not full.exists(): return "" return full.read_text(encoding="utf-8") ``` ```python # scripts/loader.py:351-359 def phase_4_targeted_lookup( self, daily_log_ref: str, section: Optional[str] = None, ) -> Optional[LoadedContent]: """Load a specific daily log or section of it.""" text = self._read(daily_log_ref) if not text: return None if section: extracted = self._extract_log_sections(text, [section]) return self._load(daily_log_ref, section, extracted, phase=4) if extracted else None return self._load(daily_log_ref, "full", text, phase=4) ``` ### Technical Analysis Although `_read()` names its argument `relative_path`, it does not enforce that requirement. The expression `self.root / relative_path` accepts traversal components such as `../` and also accepts absolute paths. In Python's `pathlib`, joining a root to an absolute path discards the root. `phase_4_targeted_lookup()` exposes this helper through a public method and does not verify that the requested file is a canonical daily log under `memory/`. There is no resolved-path containment check, filename allowlist, extension restriction, or symbolic-link defense. ### Attack Path 1. An attacker influences the `daily_log_ref` passed by the application or persuades a tool-enabled agent to perform a targeted memory lookup. 2. The supplied value is a traversal path such as `../../.env` or an absolute path such as `/etc/passwd`. 3. `_read()` joins the value to the project root without validating containment. 4. Python resolves or honors the path outside the intended workspace. 5. The file is read u ...[truncated 768 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/migrate.py:329
Finding

Personal Memory Files Are Incorrectly Classified as Safe in Any Context

Content
View full analysis
Session: {now.strftime('%H:%M')} UTC, ~{duration} min\n" f"> Thread(s) active: {threads_str}\n" ) sections.append(f"## Session Summary\n\n{summary}\n") if events: sections.append(f"## What Happened\n\n{events}\n") if self.capture.decisions: rows = ["| Decision | Reasoning | Ref |", "|----------|-----------|-----|"] for d in self.capture.decisions: ref = ", ".join(self.capture.thread_refs) if self.capture.thread_refs else "—" rows.append(f"| {d['decision']} | {d['reasoning']} | {ref} |") sections.append(f"## Decisions\n\n" + "\n".join(rows) + "\n") if self.capture.open_questions: qs = "\n".join(f"- {q}" for q in self.capture.open_questions) sections.append(f"## Open Questions (New This Session)\n\n{qs}\n") if self.capture.patterns: ps = "\n".join(f"- {p}" for p in self.capture.patterns) sections.append(f"## Pattern ...[truncated 2303 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Context Leakage

High
Category
Data Exfiltration
Confidence
87% confidence
Finding

The script reads agent daily logs and copies extracted thread names, topics, mood, and decision counts into a generated memory/index.md, which can concentrate sensitive working-memory context into a single easy-to-read file. In an agent-memory skill, those logs may contain secrets, internal plans, user data, or other sensitive context, so indexing and summarizing them increases exposure and makes unintended disclosure easier if the index is shared, committed, or surfaced to other tools.

Content

Scanner excerpt · scripts/rebuild_index.py (reported line 24)May include surrounding context.

python
text = log_path.read_text(encoding="utf-8")
    date = log_path.stem  # YYYY-MM-DD

    # Extract threads from header
    threads_match = re.search(r"Thread\(s\) active:\s*(.+)", text)
    threads = threads_match.group(1).strip() if threads_match else "—"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill clearly instructs running scaffold and migration scripts that read and write project files, but it declares no explicit tool scope or permissions. In an agent environment, this can lead to file modification capabilities being invoked without transparent constraint or user awareness, increasing the chance of unintended writes to AGENT.md, MEMORY.md, and memory/ files.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description says the skill triggers on broad phrases like 'AGENT.md', 'working memory', and 'make my agent remember', which can cause activation in contexts where the user did not intend filesystem changes. Because this skill performs scaffolding, migration, and auto-patching, accidental activation could lead to unsolicited analysis or project file modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill description emphasizes setup and migration behavior but does not clearly warn that it may create files, patch AGENT.md, back up and restructure MEMORY.md, and rebuild indexes. In a security-sensitive agent workflow, missing up-front disclosure reduces informed consent and makes destructive or surprising file changes more likely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The workflow instructs the agent to write and update multiple memory files at session end, but it does not require explicit user confirmation, preview, or safeguards before modifying persistent files. In a file-management skill, this creates a real risk of unintended overwrites, thread closure mistakes, or state corruption if the agent misinterprets the session or operates on the wrong workspace.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The migration script injects new policy text into AGENT(S).md that hard-codes session-type restrictions such as 'MAIN SESSION ONLY' for several memory files. Because this is done automatically during migration, it silently alters agent behavior and trust boundaries without explicit user approval, potentially causing denial of access to relevant context or introducing hidden policy constraints that persist across future sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code persistently writes detailed session content, including summaries, events, decisions, open questions, emotional notes, and structured event text, directly to disk with no notice, consent flow, sensitivity filtering, or redaction. In the context of an agent memory skill, this can capture personal, confidential, or regulated data supplied during normal interactions, creating a privacy and data-handling risk even if the behavior is intentional product functionality.

Content

No source excerpt is available for this finding.