Back to skill

Security audit

memU: Persistent Memory for 24/7 Agents

Security checks for vulnerabilities and agentic risk

Overview

This skill is not malicious, but it needs review because its examples store long-term user data and show unsafe deployment patterns that could expose or poison that memory.

Review this carefully before installing. Use isolated environments, pin dependencies, avoid the default PostgreSQL password and public port binding, scope every memorize and retrieve call by user or tenant, treat retrieved memory as untrusted reference data rather than system instructions, and do not store secrets, regulated data, email contents, logs, or customer data unless you have explicit consent, redaction, retention, and deletion controls.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
README.md:302
Finding

Persistent Prompt Injection Through Untrusted Memory Content

Content
View full analysis

Vulnerability Details

File Location: README.md:302-323
Additional Location: examples/example_2_openclaw_integration.py:57-73, 78-88
Vulnerability Type: Persistent stored-prompt injection
Risk Level: High

Vulnerable Code

python
# Hook into OpenClaw's message handler
async def on_message(message, agent_context):
    # Store the interaction
    await memu_service.memorize(
        resource_payload=[
            {"role": "user", "content": message.content},
        ],
        modality="conversation",
        user={"user_id": message.author_id},
    )

    # Retrieve context for response generation
    memories = await memu_service.retrieve(
        query=[{"role": "user", "content": message.content}],
        method="embedding",
    )

    # Inject memory into agent's system prompt
    memory_context = "\n".join(
        f"- [{m.category}] {m.content}" for m in memories
    )
    agent_context.system_prompt += f"\n\nRelevant memory:\n{memory_context}"

The executable integration example implements the same unsafe pattern:

python
memories = await self.memory.retrieve(
    query=[{"role": "user", "content": message}],
    method="embedding",
)

memory_lines = [f"- [{m.category}] {m.content}" for m in memories]
memory_context = "\n".join(memory_lines) if memory_lines else "(no relevant memory)"

system_prompt = (
    "You are a helpful assistant. Use the following memory context "
    "to provide informed, personalized responses.\n\n"
    f"Relevant memory:\n{memory_context}"
)
print(f"System prompt with {len(memories)} memory items injected.")
print(f"Memory context:\n{memory_context}\n")

Technical Analysis

User-controlled message content is submitted to persistent memory. Retrieved memory content is subsequently concatenated directly into the agent's privileged system prompt without:

  • Treating the retrieved content as untrusted data
  • Separating data from executable model instructions
  • Detecting or filtering ins ...[truncated 2110 chars]
Remediation
View remediation

Remediation Suggestions

  1. Never concatenate retrieved memory directly into the system prompt. Place it in a separate, clearly delimited message identified as untrusted reference data.
  2. Add a fixed system instruction stating that memory content may contain untrusted text and must never be interpreted as instructions.
  3. Apply the authenticated user or tenant identifier to every write and retrieval operation.
  4. Enforce record-level authorization after retrieval and before returning memory to the model.
  5. Store provenance, creator identity, trust level, and tenant ownership with each memory item.
  6. Reject, quarantine, or require confirmation for memories containing instruction-like phrases, requests to ignore policy, tool commands, or secret-exfiltration directives.
  7. Prefer structured memory fields over unrestricted text and validate all fields against an allowlist.
  8. Limit the number and size of retrieved items and escape or encode control-like content.
  9. Require explicit human approval before retrieved memory can influence privileged or destructive tool operations.
  10. Add tests covering persistent prompt injection and cross-user retrieval.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:64
Finding

Unpinned Third-Party Package Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:64-67
Additional Locations: README.md:81-84; requirement blocks in all four Python examples
Vulnerability Type: Unpinned dependency and supply-chain exposure
Risk Level: Medium

Vulnerable Code

bash
pip install memu-py

The production example also recommends an unpinned installation:

text
Requirements:
    pip install memu-py httpx
    PostgreSQL 16 with pgvector running
    export OPENAI_API_KEY=sk-your-key
    export MEMU_DB_URL=postgresql://user:pass@host:5432/memu

Technical Analysis

The installation instructions request the newest package versions accepted by the package index at installation time. The project supplies no exact version constraint, dependency lockfile, package hash, or integrity-verification procedure.

Installation and import of a Python package can execute package-controlled code. In this project, memu-py is subsequently provided with an API key and processes conversation and memory data. A compromised package-index account, malicious replacement package, or unsafe future release could therefore affect environments that follow the documented command.

This finding does not establish that the current memu-py package is malicious. The vulnerability is that the reviewed project does not ensure that users install the same dependency artifact that was intended or audited.

Attack Path

  1. An upstream package, publisher account, release process, or transitive dependency is compromised, or a future incompatible release is published.
  2. A user follows the documented pip install memu-py command.
  3. The package manager resolves and installs the newly available artifact rather than a known audited version.
  4. Package installation or imported runtime code executes with the user's privileges.
  5. The dependency can access process environment variables such as OPENAI_API_KEY, application inputs, memory content, database credentials, and files acce ...[truncated 622 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin memu-py and all direct dependencies to exact versions that have been reviewed and tested.
  2. Provide a lockfile or hash-locked requirements file generated from a trusted environment.
  3. Require package hashes during installation, for example through pip install --require-hashes.
  4. Verify package publisher identity, release provenance, and signatures where available.
  5. Use a private or allowlisted package mirror for production deployments.
  6. Run dependency vulnerability and software-composition scans in continuous integration.
  7. Install and run the package in an isolated virtual environment or container under a non-administrative account.
  8. Restrict runtime access to environment variables, files, and outbound destinations according to least privilege.
  9. Separate optional dependencies such as httpx into explicitly pinned dependency groups.
  10. Establish an update process that reviews release notes and security changes before changing pinned versions.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:70
Finding

Public PostgreSQL Binding With Predictable Administrative Credentials

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:70-75
Additional Locations: README.md:133-149; examples/example_2_openclaw_integration.py:9-11, 44-47
Vulnerability Type: Insecure database exposure and hardcoded default credentials
Risk Level: High

Vulnerable Code

bash
docker run -d --name memu-postgres \
  -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=memu -p 5432:5432 pgvector/pgvector:pg16

The integration example embeds the same credentials in the connection string:

python
database_config={
    "provider": "postgresql",
    "url": "postgresql://postgres:postgres@localhost:5432/memu",
},

The expanded README command likewise publishes the database port:

bash
docker run -d --name memu-postgres \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=memu \
  -p 5432:5432 \
  pgvector/pgvector:pg16

Technical Analysis

Docker's -p 5432:5432 syntax generally binds the container port to all host interfaces unless the Docker daemon or host networking configuration restricts it. At the same time, the database is configured with the predictable administrative username and password postgres/postgres.

The database stores persistent agent memory derived from conversations, documents, operational data, and user preferences. If port 5432 is reachable from another host, an attacker can attempt direct authentication using the documented credentials.

Because the configured account is the PostgreSQL administrative account, a successful login is not constrained to a narrowly scoped application role. The attacker may be able to read or modify memory data and database objects.

Attack Path

  1. A user runs the documented Docker command on a workstation or server.
  2. Docker publishes PostgreSQL port 5432 on the host's reachable interfaces.
  3. A remote or local network attacker scans the host and identifies the PostgreSQL service.
  4. The attacker authenticates ...[truncated 1180 chars]
Remediation
View remediation

Remediation Suggestions

  1. Bind the published database port to loopback when remote access is unnecessary:
bash
-p 127.0.0.1:5432:5432
  1. Prefer an internal Docker network and avoid publishing PostgreSQL to the host entirely when only application containers require access.
  2. Generate a cryptographically strong, unique password and supply it through a secret manager or protected environment file.
  3. Create a dedicated least-privileged application role rather than using the postgres administrator account.
  4. Remove plaintext credentials from code and documentation connection strings.
  5. Restrict ingress with host firewalls, cloud security groups, and network allowlists.
  6. Require TLS for database connections crossing an untrusted network and verify the server certificate.
  7. Separate tenants at the database, schema, or enforced row-security level as appropriate.
  8. Rotate credentials immediately if the documented defaults have been deployed on a reachable system.
  9. Add deployment checks that reject default passwords and unrestricted listener configurations.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description presents a persistent memory system for continuous agents, but the supplied code chunk is explicitly a minimal in-memory demo that does not provide persistence and resets on restart. Its primary purpose is to illustrate basic memU usage rather than implement the described persistent infrastructure. It also connects to the OpenAI API using an API key from the environment, which is an external resource access not reflected in the declared permissions. While the code is related to memory retrieval with memU, the persistence and production-oriented aspects in the description are materially inconsistent with this specific code chunk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The FAQ explicitly states that memU can use external LLMs and a hosted Cloud API, and that raw inputs/conversations are sent to those services for memorization and retrieval-related processing, but it does not clearly warn users that sensitive conversation data may leave their environment. In a persistent memory skill, this omission is security-relevant because operators may unintentionally transmit confidential or regulated data to third parties without informed consent or appropriate controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README encourages persistent storage of conversations, documents, images, logs, and user-linked memory while emphasizing proactive retrieval, but it does not prominently warn about privacy, retention, consent, or sensitive-data handling. In a memory skill specifically designed to accumulate long-term user context, omission of these warnings can lead operators to ingest sensitive personal or operational data without adequate safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The hosted API example sends raw conversation payloads to a remote cloud service but does not clearly disclose that user content leaves the local environment and is processed by a third party. For a memory system handling long-lived conversational and document data, this can cause unintended exposure of sensitive information and compliance issues if operators assume processing is local.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises environment and network-dependent behavior via metadata and example code, but does not declare an explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, this weakens least-privilege controls and makes it harder for operators to understand that the skill can access secrets and transmit data externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill is explicitly about persistent memory and shows conversation content being sent to an external OpenAI endpoint, yet it does not prominently warn that user data may be retained across sessions and transmitted to third-party APIs. In a long-term memory skill, this omission is especially dangerous because users may unknowingly store sensitive information indefinitely or outside their trust boundary.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
79% confidence
Finding

The Docker example pulls and runs an image without pinning a specific version tag or digest, which can lead to non-reproducible deployments and exposure to unexpected upstream changes or a compromised latest image. For infrastructure components handling persistent memory, that increases supply-chain risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The example configures outbound transmission of memory/query content to the OpenAI API, which can expose sensitive conversational data to an external service if used without appropriate controls. This is not inherently malicious, but in a memory skill the risk is amplified because historical user data may be forwarded for both storage-related reasoning and retrieval workflows.

Content

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

md
llm_profiles={
        "default": {
            "provider": "openai",
            "base_url": "https://api.openai.com/v1",
            "api_key": "sk-your-key",
            "chat_model": "gpt-4o-mini",
            "embed_model": "text-embedding-3-small",

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a memory infrastructure skill focused on persistent memory architecture and retrieval. In this example, the code reads an OPENAI_API_KEY from the environment and configures remote calls to https://api.openai.com/v1 for chat and embedding models, introducing credential handling and third-party network dependence beyond what the manifest explicitly states.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes this skill as persistent memory infrastructure that replaces flat-file memory with a hierarchical memory architecture. In this example, the code additionally requires an external OpenAI API key and sets up remote LLM and embedding service access, which is not inherently required just to provide persistent storage or memory organization.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code retrieves persistent memories derived from user conversations and prepares them for use with an external OpenAI service, but the example provides no consent, notice, or filtering for sensitive content. In an always-on memory system, the combination of long-term storage plus external model processing increases privacy and data-governance risk because historical user data may be transmitted off-box unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code configures MemoryService to use OpenAI at https://api.openai.com/v1 and later sends payload and query content for memorization and retrieval. Although the module docstring lists required environment variables, it does not warn that user content will be sent to a third-party network service, which is a safety-relevant disclosure for code handling potentially sensitive data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 98)May include surrounding context.

md
llm_profiles={
            "default": {
                "provider": "openai",
                "base_url": "https://api.openai.com/v1",
                "api_key": api_key,
                "chat_model": "gpt-4o-mini",
                "embed_model": "text-embedding-3-small",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 289)May include surrounding context.

md
llm_profiles={
            "default": {
                "provider": "openai",
                "base_url": "https://api.openai.com/v1",
                "api_key": api_key,
                "chat_model": "gpt-4o-mini",
                "embed_model": "text-embedding-3-small",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · examples/example_1_minimal.py (reported line 32)May include surrounding context.

python
llm_profiles={
            "default": {
                "provider": "openai",
                "base_url": "https://api.openai.com/v1",
                "api_key": api_key,
                "chat_model": "gpt-4o-mini",
                "embed_model": "text-embedding-3-small",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · examples/example_2_openclaw_integration.py (reported line 38)May include surrounding context.

python
llm_profiles={
            "default": {
                "provider": "openai",
                "base_url": "https://api.openai.com/v1",
                "api_key": api_key,
                "chat_model": "gpt-4o-mini",
                "embed_model": "text-embedding-3-small",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · examples/example_3_production.py (reported line 72)May include surrounding context.

python
llm_profiles={
            "default": {
                "provider": "openai",
                "base_url": "https://api.openai.com/v1",
                "api_key": api_key,
                "chat_model": "gpt-4o-mini",
                "embed_model": "text-embedding-3-small",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · examples/example_4_scenarios.py (reported line 32)May include surrounding context.

python
llm_profiles={
            "default": {
                "provider": "openai",
                "base_url": "https://api.openai.com/v1",
                "api_key": api_key,
                "chat_model": "gpt-4o-mini",
                "embed_model": "text-embedding-3-small",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code sends user conversation content and later retrieval queries to the OpenAI-backed MemoryService, including research interests and other personal/contextual data, but provides no user-facing disclosure beyond internal comments/docstrings. For code files, network transmission of user or system data should have some visible warning, prompt, or explicit disclosure unless clearly surfaced elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The email triage scenario memorizes and queries email-priority information that may reveal sensitive organizational communications patterns, and these requests are configured to use the OpenAI API. The file has no user-facing warning, confirmation, or disclosure that such data is sent off-box to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This scenario sends service names, incident thresholds, and alert-context data to a remote OpenAI endpoint via MemoryService. Operational telemetry and incident patterns can be sensitive, but the code lacks any visible disclosure, confirmation, or warning to the user about this network transmission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The release text promotes proactive memory retrieval and long-lived agent memory but does not mention privacy, retention, consent, or sensitive-data handling. In a memory infrastructure skill, this omission can encourage adopters to deploy persistent collection and retrieval patterns without appropriate safeguards, increasing the chance of over-collection or unintended exposure of user and system data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The example prints retrieved memory context directly to stdout, which can expose prior conversation content, personal data, operational details, or secrets stored in memory to logs, terminals, or shared observability systems. In a persistent-memory agent, this is more dangerous because historical sensitive data may be surfaced and leaked beyond the intended memory subsystem.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.