Back to skill

Security audit

Agent Memory Enterprise

Security checks for vulnerabilities and agentic risk

Overview

This memory skill is not malicious, but it needs Review because it persistently stores and reuses user, task, conversation, and document data without strong tenant isolation or prompt-safety controls.

Review before installing in any shared or enterprise environment. Only deploy behind application-level authentication and tenant isolation, configure approved Redis/PostgreSQL/ChromaDB storage, avoid indexing secrets or regulated data, add retention/deletion controls, and treat all retrieved memory as untrusted before sending it to an LLM.

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
  • 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

Error
Location
scripts/agent_memory/injection/injector.py:61
Finding

Persistent Untrusted Memory Is Injected Verbatim into LLM Prompts

Content
View full analysis
str: """Format a knowledge search result.""" if not result: return "" source = f" (from: {result.document_title})" if result.document_title else "" return f"[Knowledge{source}]\n{result.content}" ``` `scripts/agent_memory/injection/injector.py:61-91`: ```python # Build memory sections sections: list[tuple[str, str]] = [] used_tokens = 0 for item, score in sorted_memories: formatted = self._format_item(item, score.memory_type) if not formatted: continue tokens = self.estimate_tokens(formatted) if used_tokens + tokens <= available: sections.append((score.memory_type.value, formatted)) used_tokens += tokens else: # Try a shorter version (first line only) short = formatted.split("\n")[0] short_tokens = self.estimate_tokens(short) if used_tokens + short_tokens <= available: sections.append((score.memory_type.value, short + "...")) used_tokens += short_tokens ...[truncated 2600 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/agent_memory/memories/experience_memory.py:96
Finding

Missing Ownership Enforcement Enables Cross-User Memory Access and Poisoning

Content
View full analysis
str: async with self._pg.session_factory() as session: model = ExperienceRecordModel( task_type=data.task_type, goal_description=data.goal_description, approach=data.approach, outcome=data.outcome.value, duration_seconds=data.duration_seconds, domain=data.domain, steps_taken=data.steps_taken, error_info=data.error_info, tags=data.tags, access_count=data.access_count, user_id=data.user_id, ) ``` However, `scripts/agent_memory/memories/experience_memory.py:96-128` does not use that owner identifier during similarity retrieval: ```python async def find_similar( self, goal_description: str, task_type: Optional[str] = None, domain: Optional[str] = None, min_success_rate: Optional[float] = None, ) -> list[ExperienceRecord]: """Find similar experiences using keyword matching and filters.""" rate = min_success_rate or self._config.min_success_rate async with self._pg.session_factory() as session: stmt = select(ExperienceRecordModel) if task_type: stmt = stmt.where(ExperienceRecordModel.task_type == task_type) if domain: stmt = stmt.where(ExperienceRecordModel.domain == domain) # Filter by outcome success for success-rate calculati ...[truncated 4850 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a full production-grade agent memory system with storage backends and advanced memory orchestration. However, the supplied code is limited to prompt formatting utilities for rendering conversation history, task state, user preferences, knowledge results, and past experiences as strings. These functions are plausibly a small supporting part of a memory system, but this chunk does not implement the core advertised capabilities. Therefore the description materially overstates what this code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a broad, enterprise-grade memory platform with multiple layers, routing, scoring, and support for several storage backends. This code chunk, however, is narrowly focused on one memory subtype: conversation context stored in Redis. It provides CRUD-like operations for session messages, sliding-window retrieval, trimming by message count and token count, optional TTL expiry, and session clearing. While Redis support is consistent with part of the declaration, the chunk does not implement or demonstrate the larger claimed capabilities such as multi-backend storage, PostgreSQL or ChromaDB integration, routing, or scoring. Because the declared purpose substantially overstates what this specific code actually does, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad, production-oriented agent memory platform with multiple layers, routing, scoring, and support for PostgreSQL, Redis, and ChromaDB. The supplied code chunk is much narrower: it defines only an ExperienceMemory class backed by PostgreSQL models and sessions. Its functionality is limited to CRUD operations, simple search based on word overlap in goal descriptions, success-rate filtering, and pattern consolidation. There is no evidence in this chunk of a 5-layer system, backend routing, Redis/ChromaDB integration, or richer scoring/storage orchestration. While the code does fit a subset of the declared memory theme, the description materially overstates the implemented capabilities of this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The description presents a broad, production-grade multi-layer memory platform with routing, scoring, and support for PostgreSQL, Redis, and ChromaDB. The supplied code chunk is much narrower: it defines a KnowledgeMemory class that chunks text, stores and queries document chunks in ChromaDB, and supports retrieval/deletion operations. While similarity scoring is present in a limited form and ChromaDB support aligns partially with the description, the chunk does not implement or expose a 5-layer architecture, backend routing, or PostgreSQL/Redis storage. This is therefore a material description/behavior mismatch, with the code representing only one specialized subcomponent of the claimed overall system.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description portrays a broad, multi-backend, enterprise memory system with routing and scoring capabilities. The supplied code chunk is much narrower: it is a single TaskMemory class that stores and manages structured task state in PostgreSQL using SQLAlchemy. It supports task creation, retrieval, search, deletion, counting, step updates, checkpoints, and validated task-status transitions. There is no evidence here of routing, scoring, Redis integration, ChromaDB integration, or a broader 5-layer memory architecture. While this file could be one component within such a larger system, the code chunk itself does not accurately match the declared description, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The code chunk is a focused UserMemory class, not a full production-grade agent memory platform. It uses PostgreSQL and Redis, but there is no routing logic, no scoring, and no ChromaDB integration in this snippet. Its actual purpose is long-term user profile/preference persistence with caching and history tracking. That is related to the broader declared domain of agent memory, but the declared description materially overstates the capabilities and architecture represented by this code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description describes a full production memory system with multiple storage backends and higher-level behaviors such as routing and scoring. The supplied code chunk is much narrower: it contains only SQLAlchemy ORM table definitions for PostgreSQL-oriented persistence models. While these models are plausibly a supporting part of an agent memory system, this chunk by itself does not actually implement the advertised system capabilities. Therefore the description overstates what this specific code does, making it a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description presents a broad production-ready memory platform with layered architecture, routing, scoring, and multiple storage backends. The supplied code chunk, however, is only a test file for a memory injector. Its behavior is limited to validating token estimation and prompt/memory injection under a token budget. While scoring is referenced through test setup, the code does not actually implement or expose the claimed storage backends, routing, or enterprise multi-layer memory system. This is a material description-to-code mismatch because the chunk’s primary purpose is testing a specific injector component rather than delivering the declared system capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad production memory platform with multiple layers, routing, scoring, and several storage backends. The supplied code chunk is much narrower: it is a test file for one memory subtype, ExperienceMemory. It validates behaviors like record_experience, find_similar, get_success_rate, consolidate_experiences, count, and retrieve using a temporary SQLite-backed PostgresClient. There is no evidence in this chunk of Redis, ChromaDB, routing, scoring, or a full 5-layer system. Because the actual code’s purpose is materially different and substantially narrower than the declared description, this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a broad production-grade agent memory platform with multiple layers, routing, scoring, and several storage backends. The actual code chunk only contains unit/integration tests for task memory behavior, specifically using an in-memory SQLite URL through the Postgres client abstraction. It validates task creation, state transitions, checkpoints, archiving, active-task queries, counting, and deletion. While this may be a small part of a larger memory system, this chunk does not substantiate most of the claimed capabilities, especially 5-layer architecture, routing, scoring, Redis, or ChromaDB support. Therefore the description does not accurately represent what this supplied code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a production memory system with routing, scoring, and multiple storage backends. However, the supplied code is only a test module for model definitions. It checks enum constants and simple model construction/default fields, which is at most a small supporting component of such a system. There is no evidence here of backend integration, persistence, routing logic, or multi-layer memory orchestration. Because the actual code chunk's purpose is materially narrower and different from the declared purpose, this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description focuses on a production agent memory system with multi-backend persistence and routing/scoring. The actual code chunk only contains unit tests for a routing feature extractor that classifies text queries by domain, complexity, task type, context/history, and keywords. While routing is loosely related, the chunk does not demonstrate the core declared purpose of an enterprise memory system or any storage backend support. This is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
92% confidence
Finding

The example explicitly records raw conversation content into long-term/context memory and later routes and injects memory back into prompts, creating a realistic path for context leakage across sessions, tasks, or users if isolation and filtering are imperfect. In a memory skill, this is more dangerous than in ordinary docs because persistent recall is the core feature, so accidental retention of secrets, regulated data, or unrelated prior context can directly affect future model outputs.

Content

Scanner excerpt · SKILL.md (reported line 58)May include surrounding context.

md
# Initialize
system = AgentMemorySystem(config)

# Record conversation
await system.context.add_message(
    user_id="user_123",
    role="user",

Missing User Warnings

High
Category
Not specified by scanner
Confidence
93% confidence
Finding

The integration example formats retrieved memory into a prompt and sends it with the user query to an LLM, but does not warn that stored conversations or other memory artifacts may be transmitted to an external model provider. This is especially risky in an enterprise memory skill because retrieved context can aggregate sensitive user, operational, or corporate data and silently exfiltrate it outside the primary trust boundary.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill prominently promotes persistent long-term memory, user profiles, and execution history without any warning about privacy, retention, consent, or sensitive-data handling. In an agent-memory context, this increases the chance that deployers will store personal or confidential data indefinitely and surface it later in prompts or retrieval flows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The examples show storing user, task, and knowledge data in Redis, PostgreSQL, and ChromaDB without warning that the data becomes persistent and may be retrievable later. That omission is risky because users and integrators may treat examples as safe defaults and unintentionally persist sensitive conversation or profile data to external systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown API reference documents a clear_conversation(user_id: str) method that appears to delete stored conversation history, but it provides no warning that the action may remove user data or be irreversible. For markdown files, destructive behaviors that affect user data should be accompanied by an explicit warning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The examples demonstrate persistent storage of conversations and user preferences but provide no notice about retention, consent, minimization, or access controls. In an enterprise memory system, readers may copy these patterns directly, causing unnecessary collection and long-term storage of potentially sensitive personal data without appropriate privacy safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The knowledge indexing example encourages storing arbitrary document contents for later retrieval without warning that indexed material may include confidential business records, HR data, or regulated information. In this enterprise-focused context, omission of data classification and access-control guidance can lead to sensitive organizational data being ingested into searchable memory stores and exposed more broadly than intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The formatter serializes potentially sensitive user preference data, confidence scores, sources, and usage patterns directly into prompt context without any filtering, minimization, or consent boundary. In an enterprise agent-memory system, this increases the chance of unnecessary exposure of profiling data to downstream model calls, logs, prompt-injection surfaces, or external providers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code persists full conversation messages, including content and metadata, to Redis via pipe.set(...), which is a user-data write operation. The file contains no confirmation prompt, logging, or explanatory warning beyond terse internal docstrings, so users are not clearly informed that their conversation data is being stored externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This module persists user profiles, preferences, task history, and usage patterns to PostgreSQL and Redis, which is a privacy-relevant data handling operation. While the docstrings describe the storage mechanism, there is no user-facing warning, confirmation, or disclosure in the code about collecting and retaining this long-term user data.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/agent_memory/models/task.py (reported line 22)May include surrounding context.

python
class TaskState(MemoryBase):
    task_id: str = Field(default_factory=lambda: str(__import__("uuid").uuid4()))
    goal: str
    steps: list[TaskStep] = Field(default_factory=list)
    current_step_index: int = 0

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The models persist task goals, results, checkpoint data, and linked user identifiers, and later also store experience records and steps taken. These are safety-relevant file/database writes involving potentially sensitive user or system data, but this file provides no visible disclosure or explanatory comments about that retention.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.