Back to skill

Security audit

Agent Memory 1

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward local persistent-memory skill, but users should treat stored memories as sensitive and review what gets saved.

Install only if you want local cross-session memory. Avoid storing secrets, credentials, confidential user data, or unreviewed instructions; review and prune the database periodically; use an explicit database path with appropriate filesystem permissions; and make sure any agent consuming recalled memories treats them as data, not as higher-priority instructions.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T02 · Agent Memory Poisoning

Warning
Location
SKILL.md:45
Finding

Untrusted conversation content can poison persistent agent memory

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:45-59; supporting implementation in src/memory.py:180-218 and src/memory.py:383-410
Vulnerability Type: Persistent memory poisoning
Risk Level: Medium

Vulnerable Code

markdown
## Integration with Clawdbot

Add to your AGENTS.md or HEARTBEAT.md:

```markdown
## Memory Protocol

On session start:
1. Load recent lessons: `mem.get_lessons(limit=5)`
2. Check entity context for current task
3. Recall relevant facts

On session end:
1. Extract durable facts from conversation
2. Record any lessons learned
3. Update entity information
text

The corresponding storage operation accepts arbitrary content without a trust or review state:

```python
def remember(self, content: str, tags: List[str] = None,
             source: str = "conversation", confidence: float = 1.0,
             expires_in_days: int = None) -> str:
    """
    Store a fact in memory.

    Args:
        content: The fact to remember
        tags: Categories/labels for the fact
        source: Where this fact came from (conversation, observation, inference)
        confidence: How confident we are (0-1)
        expires_in_days: Auto-expire after N days (None = never)

    Returns:
        The fact ID
    """
    fact_id = self._generate_id(content)
    now = self._now()
    tags = tags or []

    expires_at = None
    if expires_in_days:
        expires_at = (datetime.utcnow() + timedelta(days=expires_in_days)).isoformat()

    conn = sqlite3.connect(self.db_path)
    cursor = conn.cursor()

    cursor.execute("""
        INSERT INTO facts (id, content, tags, source, confidence,
                         created_at, last_accessed, access_count, expires_at)
        VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?)
    """, (fact_id, content, json.dumps(tags), source, confidence,
          now, now, expires_at))

    cursor.execute("""
        I
...[truncated 3534 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat all recalled facts, lessons, and entity attributes as untrusted data rather than executable instructions.
  2. Add immutable provenance fields, including origin identity, conversation identifier, ingestion method, creation actor, and whether the content was user-approved.
  3. Introduce trust states such as unreviewed, verified, and rejected; only load verified behavioral lessons into agent context.
  4. Require explicit user confirmation before persisting rules, credentials, security decisions, tool-use policies, or other behavior-changing material.
  5. Detect and quarantine instruction-like records, especially content containing requests to ignore constraints, invoke tools, reveal secrets, or modify future behavior.
  6. Render recalled records inside explicit data delimiters with a system-level instruction that memory content must never override current policies or higher-priority instructions.
  7. Restrict the startup protocol to narrowly relevant, trusted records instead of automatically loading recent lessons.
  8. Provide interfaces to inspect, audit, correct, and delete stored records, including the ability to identify every record created from a particular conversation.
  9. Add tests demonstrating that attacker-supplied instructions are not automatically promoted into trusted long-term guidance.

T09 · Insecure Skill Coding Practices

Warning
Location
src/memory.py:96
Finding

Sensitive persistent memory is created without enforced access permissions

Content
View full analysis

Vulnerability Details

File Location: src/memory.py:96-104 and src/memory.py:106-166
Vulnerability Type: Insecure plaintext storage and filesystem permissions
Risk Level: Medium

Vulnerable Code

python
def __init__(self, db_path: str = None):
    """
    Initialize memory storage.

    Args:
        db_path: Path to SQLite database. Defaults to ~/.agent-memory/memory.db
    """
    if db_path is None:
        db_dir = Path.home() / ".agent-memory"
        db_dir.mkdir(exist_ok=True)
        db_path = str(db_dir / "memory.db")

    self.db_path = db_path
    self._init_db()

The database is then opened without verifying ownership, file type, or access mode:

python
def _init_db(self):
    """Initialize database schema."""
    conn = sqlite3.connect(self.db_path)
    cursor = conn.cursor()

    cursor.execute("""
        CREATE TABLE IF NOT EXISTS facts (
            id TEXT PRIMARY KEY,
            content TEXT NOT NULL,
            tags TEXT,
            source TEXT DEFAULT 'conversation',
            confidence REAL DEFAULT 1.0,
            created_at TEXT NOT NULL,
            last_accessed TEXT NOT NULL,
            access_count INTEGER DEFAULT 1,
            expires_at TEXT,
            superseded_by TEXT,
            embedding TEXT
        )
    """)

    cursor.execute("""
        CREATE TABLE IF NOT EXISTS lessons (
            id TEXT PRIMARY KEY,
            action TEXT NOT NULL,
            context TEXT NOT NULL,
            outcome TEXT NOT NULL,
            insight TEXT NOT NULL,
            created_at TEXT NOT NULL,
            applied_count INTEGER DEFAULT 0
        )
    """)

    cursor.execute("""
        CREATE TABLE IF NOT EXISTS entities (
            id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            entity_type TEXT NOT NULL,
            attributes TEXT,
            first_seen TEXT 
...[truncated 2481 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create the default directory with mode 0700 and verify the effective permissions after creation.
  2. Create or chmod the database to mode 0600; fail closed if secure permissions cannot be established.
  3. Verify that the database and parent directory are owned by the expected operating-system user.
  4. Reject symbolic links and unexpected non-regular files where the deployment model permits, using race-resistant file-opening techniques when possible.
  5. Validate custom paths and warn or refuse to use world-readable, group-readable, or shared locations.
  6. Document clearly that memory is stored in plaintext and may contain sensitive conversation-derived information.
  7. Offer encryption at rest or integrate with an operating-system key store for deployments that retain sensitive data.
  8. Apply data minimization and retention controls so secrets, credentials, and unnecessary personal information are not persisted.
  9. Add automated tests that assert restrictive directory and database permissions and cover insecure pre-existing paths.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (6)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly promotes persistent storage of facts, lessons, and relationship data across sessions, including personal preferences and named individuals, but does not warn users about privacy, retention, or sensitivity of the stored data. In an agent-memory skill, this omission is materially risky because operators may persist personal or sensitive user context to disk by default without informed consent or safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README documents delete and cleanup operations such as forgetting facts and bulk removal of stale data without warning that these actions may be irreversible and can remove useful or compliance-relevant records. While not an exploit primitive by itself, the lack of caution increases the chance of accidental data loss in a persistent-memory component where users may assume recoverability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill explicitly instructs agents to persist conversation-derived facts, lessons, and entity information across sessions, but it does not warn users about retention, sensitivity, consent, or privacy risks. In an agent context, this can lead to storage of personal data, confidential project details, or other sensitive content without user awareness, increasing the chance of privacy violations and unintended data exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module silently creates a persistent SQLite database under the user's home directory and stores arbitrary facts, lessons, and entity attributes, which can easily include sensitive personal or organizational data. In an agent context, users may not realize their prompts, observations, or inferred information are being retained across sessions, increasing privacy and data-retention risk if the host is shared, backed up, or later inspected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The forget and forget_stale methods permanently delete facts from storage, including automated cleanup based on age and access count. These destructive operations have docstrings but no visible warning, confirmation prompt, or user-facing notice indicating that data will be irreversibly removed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The example initializes persistent local storage at a fixed path under /tmp and proceeds to store potentially personal or sensitive information such as a boss's preferences, a person's profile, and project metadata without any warning about persistence, access controls, or privacy implications. While this is only sample code, users may copy it directly and unintentionally retain sensitive data on disk where other local users, backups, or forensic processes could access it.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.