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## 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
## 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## 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
## 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
Content
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)
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.

Missing User Warnings

High
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.

Credential Access

High
Category
Privilege Escalation
Content
## Setup

1. Get API key from https://memoryai.dev
2. Edit `{baseDir}/config.json`:
```json
{
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

High
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.

Lp3

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.

Ssd 3

Medium
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.

Vague Triggers

Medium
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.

Ssd 3

Medium
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.

Missing User Warnings

Medium
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.

Description-Behavior Mismatch

Medium
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.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

Intent-Code Divergence

Low
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.

Static analysis

No suspicious patterns detected.