Back to skill

Security audit

Mema Brain

Security checks for vulnerabilities and agentic risk

Overview

This memory skill is mostly purpose-aligned, but its Redis memory can be sent to a remote service without built-in authentication or TLS despite documentation implying local-only storage.

Install only if you intend to use a local or otherwise strongly protected Redis instance. Avoid putting secrets or instruction-like content in mental state, and do not point REDIS_HOST at a remote service unless you provide network controls, authentication, and encrypted transport outside this skill. Prefer a pinned Redis client version before production use.

Vulnerability Patterns
  • 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
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mema.py:69
Finding
Redis mental-state data lacks authentication and transport security<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mema.py:13-15, 69-100` **Vulnerability Type**: Unauthenticated and unencrypted remote state storage **Risk Level**: High ### Vulnerable Code ```python REDIS_HOST = os.getenv("REDIS_HOST", "localhost") REDIS_PORT = int(os.getenv("REDIS_PORT", 6379)) REDIS_PREFIX = "mema:mental" ``` ```python def mental_op(action, key=None, value=None, ttl=21600): r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, decode_responses=True) if action == "set": if not key: print("Error: key is required for 'set' action", file=sys.stderr) return False if value is None: print("Error: value is required for 'set' action", file=sys.stderr) return False full_key = f"{REDIS_PREFIX}:{key}" r.set(full_key, value, ex=ttl) print(f"✓ Set {key} (TTL: {ttl}s)") return True elif action == "get": if not key: print("Error: key is required for 'get' action", file=sys.stderr) return False full_key = f"{REDIS_PREFIX}:{key}" val = r.get(full_key) print(val if val else "(nil)") return True elif action == "list": for k in r.scan_iter(match=f"{REDIS_PREFIX}:*"): print(k.replace(f"{REDIS_PREFIX}:", "")) return True elif action == "clear": if key: full_key = f"{REDIS_PREFIX}:{key}" r.delete(full_key) print(f"✓ Cleared {key}") else: keys_to_delete = list(r.scan_iter(match=f"{REDIS_PREFIX}:*")) if keys_to_delete: r.delete(*keys_to_delete) print("✓ Cleared all mental state") return True return False ``` ### Technical Analysis The Redis endpoint is configurable through `REDIS_HOST`, but the client is instantiated without a username, password, TLS, or server-certificate verification. The default loopback configuration limits ...[truncated 1987 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Keep Redis bound to loopback by default and reject non-loopback hosts unless remote operation is explicitly enabled. 2. Add support for Redis ACL credentials through protected environment variables or a secret manager: - `REDIS_USERNAME` - `REDIS_PASSWORD` 3. Require TLS for remote endpoints by using `rediss://` or `redis.Redis(..., ssl=True)`. 4. Enable server-certificate validation and provide a trusted CA bundle; do not disable hostname verification. 5. Configure Redis network controls so that only authorized clients can reach the service. 6. Use a dedicated Redis account restricted to the required key prefix and commands. 7. Treat all retrieved state as untrusted data. Do not insert it into system or developer instruction contexts without validation and clear data boundaries. 8. Consider authenticating stored values, such as with an application-level MAC, when integrity against Redis-side modification is required. 9. Update `SKILL.md` to disclose that configuring a remote Redis host transmits and stores data outside the local machine. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Redis dependency uses an unbounded version range<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1` **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Medium ### Vulnerable Code ```text redis>=5.0.0 ``` The dependency is installed through the command declared in `SKILL.md:4`: ```json "install":[{"id":"pip-deps","kind":"exec","command":"pip install -r requirements.txt"}] ``` ### Technical Analysis The requirement permits any present or future `redis` release with a version equal to or greater than `5.0.0`. Consequently, installations performed at different times may resolve to different, unreviewed package versions. The package name is consistent with the implementation, and the audited project contains no evidence of typosquatting or a currently malicious package. The risk arises from the absence of an upper bound, exact lock, and integrity hashes. A future compromised, incompatible, or unexpectedly changed release could be installed automatically without a corresponding project review. Python packages may execute build or installation logic and are imported into the runtime process. Therefore, dependency resolution is part of the project's trusted code-execution supply chain. ### Attack Path 1. A future unsafe or compromised release of the `redis` package is published and satisfies `redis>=5.0.0`. 2. A user installs the Skill dependencies with `pip install -r requirements.txt`. 3. Pip resolves the unsafe release because no exact version or hash restricts the selection. 4. Package installation, import, or runtime behavior executes code that was not reviewed with this Skill. 5. The code runs with the permissions of the user installing or invoking the Skill. ### Impact Assessment A compromised dependency could execute code with the privileges of the installing or runtime user. Depending on those privileges, it could access user-readable files, environment variables, the SQLite memory database, configured network services, and other resources available to ...[truncated 196 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the dependency to an exact reviewed version rather than using an open-ended lower bound. 2. Generate a lock file that includes all transitive dependencies. 3. Record cryptographic hashes and install with pip's `--require-hashes` option. 4. Update dependencies through a controlled process that includes changelog review, vulnerability scanning, and regression testing. 5. Use a trusted package index and prevent unintended fallback to untrusted or similarly named package sources. 6. Run dependency installation in an isolated virtual environment under a non-privileged account. 7. Periodically update the pinned version after security review instead of allowing automatic adoption of every future release. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill declares executable/install behavior and depends on environment variables and file access, but does not declare an explicit tool scope such as permissions or allowed-tools. That omission weakens reviewability and can let the skill access files or environment-supplied resources beyond what a consumer expects, especially since it manages persistent local state and connects to Redis.

Unpinned Dependencies

Low
Category
Supply Chain
Content
redis>=5.0.0
Confidence
97% confidence
Finding
The dependency is specified as `redis>=5.0.0`, which permits any future major or minor release and makes builds non-reproducible. This can silently introduce breaking changes or vulnerable versions during installation, and in a skill that manages session state and workspace knowledge, instability or vulnerable transitive behavior in the Redis client could affect confidentiality or availability of stored context.

Unverifiable Dependency: redis has 4 known advisory(ies) (CVE-2023-28858 (redis-py Race Condition vulnerability); CVE-2023-28859 (redis-py Race Condition due to incomplete fix); CVE-2023-28858 (redis-py before 4.5.3, as used in ChatGPT and other products, leaves a connectio) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding
The manifest references `redis` without pinning to a version known to be free of published advisories, so it is impossible to verify whether installations will avoid affected releases. Given known redis-py advisories, this creates supply-chain uncertainty: environments may resolve to vulnerable versions, and because this skill uses Redis for short-term context buffering, flaws in the client library could expose or corrupt ephemeral session data.

Static analysis

No suspicious patterns detected.