Back to skill

Security audit

Memory Hybrid Stack

Security checks for vulnerabilities and agentic risk

Overview

This skill is purpose-built for a local memory stack, but it gives broad write/delete access to memory stores and uses unsafe credential-loading patterns that deserve review before installation.

Install only if you trust the memory-stack .env file and the agents/operators who can invoke this skill. Prefer least-privilege database and Redis accounts, keep Qdrant pointed at the intended local endpoint, review all mutating SQL/Redis/Qdrant calls before running them, and harden the scripts before production use by replacing shell source parsing, limiting exported secrets, and adding confirmation for destructive actions.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/facts_sql.sh:8
Finding
Executable Shell Configuration Enables Command Execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/facts_sql.sh:8-16`, `scripts/state_kv.sh:19-24`, `scripts/qdrant_request.sh:11-16` **Vulnerability Type**: Executable configuration file / shell command injection **Risk Level**: High ### Vulnerable Code `scripts/facts_sql.sh:8-16`: ```bash ENV_FILE="${MEMORY_STACK_ENV:-$STACK_ROOT/.env}" if [[ ! -f "$ENV_FILE" ]]; then echo "[facts_sql] Missing env file: $ENV_FILE" >&2 exit 1 fi set -a # shellcheck disable=SC1090 source "$ENV_FILE" ``` `scripts/state_kv.sh:19-24`: ```bash ENV_FILE="${MEMORY_STACK_ENV:-$STACK_ROOT/.env}" if [[ -f "$ENV_FILE" ]]; then set -a # shellcheck disable=SC1090 source "$ENV_FILE" ``` `scripts/qdrant_request.sh:11-16`: ```bash ENV_FILE="${MEMORY_STACK_ENV:-$STACK_ROOT/.env}" if [[ -f "$ENV_FILE" ]]; then set -a # shellcheck disable=SC1090 source "$ENV_FILE" ``` ### Technical Analysis All three scripts load the stack configuration by using Bash's `source` command. An environment file sourced this way is executable shell code, not merely a collection of configuration values. It may contain command substitutions, function calls, redirections, or arbitrary commands. The `MEMORY_STACK_ENV` variable also permits callers to select a different file. Therefore, exploitation is possible if an attacker can modify the default `.env`, influence `MEMORY_STACK_ENV`, or otherwise cause a malicious file to be selected. Loading connection configuration is necessary for the Skill's declared functionality, but executing that configuration as shell code exceeds the minimum privilege required. The vulnerability is not evidence that the included `.env` is currently malicious. It creates a command-execution boundary that depends entirely on the integrity of an external file. ### Attack Path 1. An attacker obtains write access to the default memory-stack `.env`, or influences the environment used to launch the helper and sets `MEMORY_STACK_ENV` to an attacker-controlled ...[truncated 850 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not use `source` to parse a credential or configuration file. - Parse only an explicit allowlist of required `KEY=VALUE` entries and reject command substitutions, shell operators, malformed names, duplicate keys, and unexpected fields. - Use a structured configuration format and a parser that does not evaluate shell syntax where practical. - Resolve the selected configuration path to a canonical path and restrict it to an approved directory. - Reject configuration files with unexpected ownership or permissions. Secret-bearing files should normally be owned by the service account and readable only by that account. - If `MEMORY_STACK_ENV` must remain supported, treat it as a privileged configuration option and validate the target before opening it. - Apply the same hardened loader consistently to all three scripts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/facts_sql.sh:13
Finding
Shared Environment File Exports Unrelated Secrets to Child Processes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/facts_sql.sh:13-16`, `scripts/state_kv.sh:21-24`, `scripts/qdrant_request.sh:13-16` **Vulnerability Type**: Excessive secret propagation / violation of least privilege **Risk Level**: Medium ### Vulnerable Code `scripts/facts_sql.sh:13-16`: ```bash set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a ``` `scripts/state_kv.sh:21-24`: ```bash set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a ``` `scripts/qdrant_request.sh:13-16`: ```bash set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a ``` ### Technical Analysis The `set -a` option marks every subsequently assigned shell variable for export. Consequently, every value loaded from the shared `.env` is inherited by child processes, even if a particular helper does not require it. For example, the Qdrant helper only needs Qdrant connection settings, but it may also export the PostgreSQL password and other entries from the shared file to `curl`. Similarly, the Redis helper can expose unrelated database configuration to `redis-cli`. This broad propagation exceeds the minimum privileges needed for each helper. The risk depends on the contents of the external `.env` and the trustworthiness of invoked binaries and local process-inspection boundaries. The audited project does not demonstrate that unrelated secrets are presently stolen, but the implementation unnecessarily expands their exposure. ### Attack Path 1. The shared `.env` contains credentials or other sensitive values not required by the selected helper. 2. The helper enables automatic export with `set -a` and loads the entire file. 3. The helper starts `psql`, `redis-cli`, or `curl`, which inherits all exported values. 4. A compromised executable, plugin, diagnostic wrapper, crash-reporting facility, or process with permission to inspect that environment obtains the unrelated secrets. 5. The exposed credentials are then used against the services or resources ...[truncated 436 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `set -a` and export only the exact values needed by each command. - Give each helper a narrowly scoped configuration: - PostgreSQL: host, port, user, database, and password. - Redis: host, port, and password. - Qdrant: host, port, URL, and any required API credential. - Prefer separate least-privilege credential files for each service rather than a shared file containing all secrets. - Construct a clean command environment with `env -i` or an equivalent allowlist where operationally practical. - Ensure service accounts and database identities are restricted to only the operations required by the memory helper. - Review the shared `.env` and remove unrelated API keys, tokens, and credentials. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/state_kv.sh:29
Finding
Redis Password Is Passed Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/state_kv.sh:29-32` **Vulnerability Type**: Credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash CLI=(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT") if [[ -n "$REDIS_PASSWORD" ]]; then CLI+=(-a "$REDIS_PASSWORD") fi ``` ### Technical Analysis When Redis authentication is enabled, the helper appends the password to the `redis-cli` argument vector through the `-a` option. Command-line arguments may be recorded by process-monitoring systems, shell tracing, debugging tools, audit facilities, or other local processes where process-inspection permissions allow it. Although access to another process's arguments is restricted on some systems, command-line transmission is an avoidable credential-exposure pattern. The finding applies only when `REDIS_PASSWORD` is nonempty. ### Attack Path 1. Redis authentication is configured and `REDIS_PASSWORD` is loaded. 2. The Agent invokes `state_kv.sh`. 3. The helper launches `redis-cli` with `-a "$REDIS_PASSWORD"`. 4. A local observer or monitoring component captures the process argument list while the command is running or from retained diagnostic records. 5. The observer uses the recovered password to connect to the configured Redis service. ### Impact Assessment An attacker who obtains the Redis password can perform operations permitted to that Redis identity. With the documented default model, this may include reading, creating, changing, or deleting volatile state, session metadata, device status, throttles, and coordination locks. Such access could disrupt Agent workflows or expose transient data. The issue does not grant access beyond the Redis service unless the credential is reused elsewhere. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Avoid placing the Redis password in the command-line argument vector. - Supply it through a narrowly scoped `REDISCLI_AUTH` environment variable or another credential mechanism supported by the deployment. - Limit the credential environment to the single `redis-cli` invocation and unset it immediately afterward. - Disable shell tracing around all secret-handling operations. - Restrict access to process inspection and ensure monitoring or diagnostic systems redact credentials. - Use a dedicated Redis ACL user limited to the required key namespace and commands (`GET`, `SET`, and `DEL`) rather than a broadly privileged credential. - Rotate the existing Redis password if command arguments may already have been logged or captured. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill exposes shell-capable workflows that can read and modify Postgres, Redis, and Qdrant, but it declares no explicit tool scope or permission boundary. That increases the chance an agent can invoke powerful local commands without clear governance, leading to unintended data access or destructive writes.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation instructs the agent to auto-load credentials from `.env` and perform raw SQL, Redis set/delete, and Qdrant write/delete operations without prominent safety warnings or approval requirements. In this context, the skill directly targets durable and volatile memory stores, so misuse could overwrite facts, erase state, or expose sensitive connection details and memory contents.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This code file issues a curl request to a configurable endpoint and may send JSON payloads or file contents supplied by the caller, but there is no confirmation prompt, logging, or explanatory comment warning that data will be transmitted over the network. Because SQP-2 applies to code files and specifically covers network/HTTP calls that transmit user or system data, this lack of disclosure is in scope.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script performs state-changing Redis operations via SET and DEL, which can overwrite or remove stored data, but it provides no confirmation prompt, logging, or user-facing warning about these effects. In this file there are also no comments or docstrings disclosing that these commands modify or delete persisted state.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The script sources an environment file into the current shell, which can expose credentials or other sensitive configuration to subsequent logic, but there is no print, comment explaining the sensitivity, or other user-facing disclosure. SQP-2 covers access to sensitive environment variables or credentials in code files when there is no warning mechanism.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The script accesses the sensitive REDIS_PASSWORD environment variable and injects it into the redis-cli command, but the file contains no warning or explanatory text that credentials are being consumed. This matches the missing-user-warning criterion for sensitive environment variable access in code files.

Static analysis

No suspicious patterns detected.