Back to skill

Security audit

MemoryAI

Security checks for vulnerabilities and agentic risk

Overview

This memory skill is coherent, but it needs Review because it is designed to send and persist broad conversation content and profile inferences to a remote configurable service with limited user controls.

Install only if you are comfortable with a third-party memory service receiving conversation text, summaries, and inferred profile information. Do not use it for secrets, credentials, regulated personal data, private business content, or sensitive chats unless you have explicit consent, a trusted endpoint, and clear retention and deletion controls. Verify the endpoint is HTTPS and trusted before adding an API key.

Vulnerability Patterns
  • 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
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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)

other

Error
Location
scripts/memory.py:185
Finding

Excessive Transmission of Complete Conversation Content to Remote Persistent Storage

Content
View full analysis

Vulnerability Details

File Location: scripts/memory.py:185-207
Vulnerability Type: Excessive Data Collection and Remote Disclosure
Risk Level: High

Relevant instruction locations: SKILL.md:54-57, SKILL.md:82-98, and SKILL.md:104-108

Complete vulnerable code snippet:

python
def cmd_track(args):
    """Track a message. Call on every user/assistant message.

    The brain keeps the context window healthy on its own and signals
    when it's time to save and continue on a clean slate.
    """
    content = args[0] if args else ""
    if not content:
        print("Usage: memory.py track \"message content\" [--role user|assistant]", file=sys.stderr)
        sys.exit(1)

    role = "user"
    i = 1
    while i < len(args):
        if args[i] == "--role" and i + 1 < len(args):
            role = args[i + 1]
            i += 2
        else:
            i += 1

    result = _api("POST", "/v1/bot/session/message", {
        "message": {"role": role, "content": content},
    })

    if result.get("rotate"):
        print("SAVE_NOW")
        if result.get("should_compress"):
            print("Action: call 'memory.py save' with a short summary of the conversation so far")
    else:
        print("OK")

Technical Analysis

The Skill documentation directs the Agent to invoke track for every user and assistant message. The implementation places the complete message content and role into a JSON request and submits it to /v1/bot/session/message on the configured remote service.

This behavior can collect credentials, source code, personal information, private conversations, authentication material, or other secrets that happen to appear in a session. It exceeds the minimum data access needed for selective long-term memory because the Skill already provides explicit store and summarized save operations.

The transmission behavior is disclosed in the ...[truncated 1507 chars]

Remediation
View remediation

Remediation Suggestions

  1. Disable per-message tracking by default and require explicit, informed user opt-in before enabling it.
  2. Replace mandatory raw-message tracking with selective storage through store or locally generated, minimal summaries.
  3. Display a clear disclosure identifying the destination, categories of collected data, retention period, and deletion process.
  4. Implement local secret detection and redaction for API keys, passwords, access tokens, private keys, session cookies, and common credential formats.
  5. Add configurable allowlists and denylists for message types and data categories.
  6. Require confirmation before transmitting messages classified as sensitive.
  7. Support short retention periods, export, deletion, and a mode that does not persist raw conversation text.
  8. Minimize stored fields and provide a local-only memory option where feasible.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/memory.py:18
Finding

Unvalidated Configurable Endpoint Can Disclose Bearer Credentials and Memory Data

Content
View full analysis

Vulnerability Details

File Location: scripts/memory.py:18-43
Vulnerability Type: Unvalidated Remote Endpoint and Plaintext Transport Exposure
Risk Level: High

Complete vulnerable code snippet:

python
def _config():
    endpoint = os.environ.get("HM_ENDPOINT", "")
    api_key = os.environ.get("HM_API_KEY", "")
    if CONFIG_PATH.exists():
        with open(CONFIG_PATH) as f:
            cfg = json.load(f)
        endpoint = endpoint or cfg.get("endpoint", "")
        api_key = api_key or cfg.get("api_key", "")
    if not endpoint or not api_key:
        print("Error: Configure endpoint + api_key in config.json or env vars", file=sys.stderr)
        sys.exit(1)
    return endpoint.rstrip("/"), api_key


def _api(method, path, body=None):
    endpoint, key = _config()
    data = json.dumps(body).encode() if body else None
    req = urllib.request.Request(
        f"{endpoint}{path}",
        data=data,
        method=method,
        headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as r:
            return json.loads(r.read().decode())
    except urllib.error.HTTPError as e:
        err = e.read().decode() if e.fp else str(e.code)
        print(f"Error {e.code}: {err}", file=sys.stderr)
        sys.exit(1)
    except urllib.error.URLError as e:
        print(f"Connection failed: {e.reason}", file=sys.stderr)
        sys.exit(1)

Technical Analysis

The endpoint can be supplied through the HM_ENDPOINT environment variable or config.json. The code concatenates that value with an API path without validating the URL scheme, hostname, port, or origin.

Consequently, the client accepts an attacker-controlled HTTPS endpoint or an unencrypted http:// endpoint. Every request includes the API key in an Authorization: Bearer header. Write requests may addition ...[truncated 1690 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse endpoints with urllib.parse.urlsplit rather than treating them as arbitrary strings.
  2. Require the https scheme and reject HTTP, file, data, and other schemes.
  3. Reject URLs containing embedded credentials, fragments, unexpected ports, or malformed hostnames.
  4. Pin or allowlist memoryai.dev as the default production origin.
  5. If custom endpoints are a required feature, require explicit setup-time confirmation and use a separate credential scoped to that origin.
  6. Warn and fail closed if the endpoint origin changes after credential configuration.
  7. Use narrowly scoped, revocable tokens and provide documented rotation procedures.
  8. Avoid storing API keys in a project JSON file; prefer a protected secret store or process environment with restrictive access controls.
  9. Add tests confirming rejection of plaintext, local-file, loopback, malformed, and unexpected external endpoints.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Tainted flow: 'req' from os.environ.get (line 35, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The endpoint is sourced from environment/config and used directly to construct outbound requests that include the bearer API key in the Authorization header. If an attacker can influence HM_ENDPOINT or config.json, they can redirect requests to an attacker-controlled server and exfiltrate credentials and all stored/recalled conversation data; in an agent memory skill, this is especially dangerous because highly sensitive long-term context is routinely transmitted.

Content

Scanner excerpt · scripts/memory.py (reported line 42)May include surrounding context.

python
headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as r:
            return json.loads(r.read().decode())
    except urllib.error.HTTPError as e:
        err = e.read().decode() if e.fp else str(e.code)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The description strongly promotes remembering user preferences, decisions, and context 'forever' but does not present an equally prominent warning that sensitive personal data may be persistently stored off-platform. Users and operators may therefore underestimate the privacy and compliance consequences of using the skill.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

Setup

  1. Get API key from https://memoryai.dev
  2. Edit {baseDir}/config.json:
json
{

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instruction to call 'track' on every user and assistant message encourages blanket capture of entire conversations without a nearby privacy warning or minimization guidance. This creates a high likelihood of persisting sensitive data, credentials, health/financial details, or other content that should not be routinely exported to long-term storage.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises and relies on environment-variable access and outbound network use via an API key and remote endpoint, but it does not declare explicit tool scope or permissions. That mismatch weakens least-privilege controls and can cause hosts or users to invoke a networked, data-exporting skill without clear authorization boundaries.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Per-message tracking and the claim that the 'brain keeps your context healthy automatically' encourage indiscriminate collection and retention across sessions. In context, this is more dangerous because the skill is specifically designed for persistent memory, so routine use can silently build a large cross-session dossier on the user.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The usage rules are broad and imperative, including 'Bootstrap at session start — always' and routine recall/store guidance, which can cause the agent to invoke the skill by default rather than only when the user has consented to persistence. In a memory skill, over-broad invocation materially increases privacy risk because it normalizes unnecessary collection and transmission of user content.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documented loop instructs agents to save session summaries whenever prompted, which operationalizes routine persistence of conversation-derived content. Session summaries often condense sensitive context and decisions, so this workflow can amplify privacy harm even if raw messages are not stored verbatim.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The store command uploads arbitrary provided content to a remote endpoint with no explicit warning that the data leaves the local environment and may be retained server-side. Given the skill's purpose of preserving long-term memory, users may send sensitive notes, credentials, or internal context that becomes remotely stored indefinitely.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill exposes a cognitive profile endpoint that returns inferred persona, mood, goals, entities, and procedures, which goes beyond ordinary memory retrieval and surfaces sensitive profiling data. In the context of a long-term memory product, this materially increases privacy risk because it aggregates and reveals behavioral inferences that could be misused for surveillance, manipulation, or sensitive attribute extraction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Fetching a cognitive profile reveals sensitive inferred information without any clear privacy warning or consent flow. Because the returned fields include mood, goals, entities, and procedures, the feature can expose intimate behavioral insights that are more sensitive than ordinary stored memories, making the skill context particularly risky.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The track command sends every user or assistant message to the remote service without any explicit disclosure at the point of use. In a memory tool designed to run continuously across sessions, silent transmission of full conversation content can capture secrets, personal data, and proprietary information far beyond what a user may expect.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The top-level docstring states that all logic resides on the server, but the code performs meaningful client-side behavior such as reading config/env credentials, parsing commands and flags, and deciding when to emit save/rotation instructions. This is an intent-level contradiction in the documentation, not merely omitted detail.

Content

No source excerpt is available for this finding.