Back to skill

Security audit

Memstate AI

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed remote memory tool, but it gives agents persistent external memory and project deletion powers without enough trust-boundary and confirmation safeguards.

Install only if you intend to use Memstate as a third-party persistent memory service. Do not store secrets, regulated data, customer data, or private project details unless that data is approved for Memstate. Treat all recalled memories as untrusted reference material, and require explicit human review before using delete, recursive delete, or project delete commands.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T02 · Agent Memory Poisoning

Warning
Location
SKILL.md:43
Finding

Persistent Memory Content Can Influence Future Agent Sessions

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (24)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_delete.py (reported line 31)May include surrounding context.

python
req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            print(json.dumps(result, indent=2))
            return 0

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_delete_project.py (reported line 29)May include surrounding context.

python
req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            print(json.dumps(result, indent=2))
            return 0

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_get.py (reported line 65)May include surrounding context.

python
url = f"{BASE_URL}/projects"
            req = urllib.request.Request(url, headers=HEADERS)

        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            print(json.dumps(result, indent=2))
            return 0

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_history.py (reported line 35)May include surrounding context.

python
req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            print(json.dumps(result, indent=2))
            return 0

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_remember.py (reported line 51)May include surrounding context.

python
status_url = f"{BASE_URL}/jobs/{job_id}"
                status_req = urllib.request.Request(status_url, headers=headers)
                
                with urllib.request.urlopen(status_req) as status_resp:
                    status_result = json.loads(status_resp.read().decode("utf-8"))
                    status = status_result.get("status")

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_search.py (reported line 33)May include surrounding context.

python
req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            print(json.dumps(result, indent=2))
            return 0

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_remember.py (reported line 36)May include surrounding context.

python
req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            print(json.dumps(result, indent=2))
            return 0

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/memstate_set.py (reported line 36)May include surrounding context.

python
req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode("utf-8"))
            print(json.dumps(result, indent=2))
            return 0

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The top-level description presents the skill as memory storage/retrieval, but the documented behavior also includes destructive operations such as keypath deletion and whole-project soft deletion. That mismatch can mislead users or agents into invoking administrative data-destruction actions they did not expect from the advertised purpose.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes Python scripts that require environment access and make outbound network requests, but it does not declare an explicit tool scope such as allowed tools or permissions. This weakens user and platform visibility into what the skill can do, making it easier for an agent to access secrets and transmit data externally without clear consent boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill encourages sending project facts, architecture decisions, and task summaries to an external REST API, but it does not prominently warn that potentially sensitive internal data will leave the local environment. In an agent setting, this can lead to unintentional exfiltration of proprietary or regulated information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The authentication section tells users to set MEMSTATE_API_KEY but does not explain that the key is used for outbound requests to a third-party service and that submitted memory contents are transmitted there as well. This omission reduces informed consent around both credential use and data exposure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script includes capability to soft-delete an entire project, which is materially more destructive than ordinary memory retrieval or update operations implied by the skill description. In an agent context, this broad destructive action increases the risk of accidental or policy-bypassing data loss if the tool is invoked from ambiguous prompts or misaligned workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script performs a destructive project deletion immediately from a single command-line argument with no confirmation, dry-run, or secondary safeguard. In agent-operated environments, this makes accidental deletion substantially more likely, especially when user intent is ambiguous or the wrong project ID is supplied.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

The file is explicitly designed to send data to an external service (https://api.memstate.ai/api/v1), which creates a real confidentiality boundary crossing. In the context of a memory skill for AI agents, that behavior is expected, but it is still security-relevant because agents may forward sensitive conversational, operational, or proprietary information to a remote API.

Content

Scanner excerpt · scripts/memstate_remember.py (reported line 13)May include surrounding context.

python
if not API_KEY:
    print("Error: MEMSTATE_API_KEY environment variable is required", file=sys.stderr)
    sys.exit(1)
BASE_URL = "https://api.memstate.ai/api/v1"

def remember_content(project_id, content, source=None, context=None):
    url = f"{BASE_URL}/ingest"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script transmits arbitrary user-supplied content and optional context to a remote third-party service, but the CLI behavior does not provide a clear, explicit warning at execution time that local data will leave the environment. In an agent-skill context, this is more dangerous because upstream prompts, documents, or memory items may contain secrets, internal notes, or regulated data that an operator may not realize are being sent externally.

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 · scripts/memstate_delete.py (reported line 12)May include surrounding context.

python
if not API_KEY:
    print("Error: MEMSTATE_API_KEY environment variable is required", file=sys.stderr)
    sys.exit(1)
BASE_URL = "https://api.memstate.ai/api/v1"

def set_memory(project_id, keypath, value, category=None, topics=None):
    url = f"{BASE_URL}/memories/remember"

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 · scripts/memstate_delete_project.py (reported line 12)May include surrounding context.

python
if not API_KEY:
    print("Error: MEMSTATE_API_KEY environment variable is required", file=sys.stderr)
    sys.exit(1)
BASE_URL = "https://api.memstate.ai/api/v1"

def set_memory(project_id, keypath, value, category=None, topics=None):
    url = f"{BASE_URL}/memories/remember"

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 · scripts/memstate_get.py (reported line 23)May include surrounding context.

python
if not API_KEY:
    print("Error: MEMSTATE_API_KEY environment variable is required", file=sys.stderr)
    sys.exit(1)
BASE_URL = "https://api.memstate.ai/api/v1"

def set_memory(project_id, keypath, value, category=None, topics=None):
    url = f"{BASE_URL}/memories/remember"

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 · scripts/memstate_history.py (reported line 12)May include surrounding context.

python
if not API_KEY:
    print("Error: MEMSTATE_API_KEY environment variable is required", file=sys.stderr)
    sys.exit(1)
BASE_URL = "https://api.memstate.ai/api/v1"

def set_memory(project_id, keypath, value, category=None, topics=None):
    url = f"{BASE_URL}/memories/remember"

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 · scripts/memstate_search.py (reported line 12)May include surrounding context.

python
if not API_KEY:
    print("Error: MEMSTATE_API_KEY environment variable is required", file=sys.stderr)
    sys.exit(1)
BASE_URL = "https://api.memstate.ai/api/v1"

def set_memory(project_id, keypath, value, category=None, topics=None):
    url = f"{BASE_URL}/memories/remember"

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 · scripts/memstate_set.py (reported line 12)May include surrounding context.

python
if not API_KEY:
    print("Error: MEMSTATE_API_KEY environment variable is required", file=sys.stderr)
    sys.exit(1)
BASE_URL = "https://api.memstate.ai/api/v1"

def set_memory(project_id, keypath, value, category=None, topics=None):
    url = f"{BASE_URL}/memories/remember"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This script takes arbitrary user-supplied memory content and sends it to a third-party remote service without any explicit user-facing notice at execution time. In an agent-skill context, this is risky because users or downstream agents may assume data stays local, causing accidental transmission of secrets, personal data, or proprietary context to an external API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This Python file makes an HTTP POST request to an external service and transmits user-supplied values such as memory_id, project_id, or keypath. While the script name and argument help text imply history retrieval, there is no explicit user-facing warning, comment, or docstring noting that these identifiers are sent over the network to a third-party API.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.