Back to skill

Security audit

redis-tools

Security checks for vulnerabilities and agentic risk

Overview

This Redis helper mostly does what it says, but it handles Redis passwords in a way that can expose them locally.

Review before installing if you may connect to real or production Redis instances. Avoid passing sensitive Redis passwords on the command line; prefer a temporary low-privilege Redis ACL user, non-production endpoints, or a safer authentication method outside shell history and process arguments.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:474
Finding
Redis Credentials Exposed Through Positional Arguments and Process Command Lines## Vulnerability Details **File Location**: `scripts/script.sh`, lines 474–482; invoked at lines 499 and 562 **Vulnerability Type**: Insecure credential handling **Risk Level**: Medium The script accepts the Redis password as a positional command-line argument and incorporates it into a command string using the `redis-cli -a` option. ```bash build_redis_cmd() { local host="$1" local port="$2" local pass="$3" local cmd="redis-cli -h $host -p $port" if [[ -n "$pass" ]]; then cmd="$cmd -a $pass --no-auth-warning" fi echo "$cmd" } ``` The generated string is subsequently assigned and executed in both connection-testing and monitoring operations: ```bash RCMD="$(build_redis_cmd "$host" "$port" "$pass")" # Test PING PONG="$($RCMD PING 2>&1 || true)" ``` ```bash RCMD="$(build_redis_cmd "$host" "$port" "$pass")" # Test connection first PONG="$($RCMD PING 2>&1 || true)" ``` ### Technical Analysis Supplying a secret as a positional argument exposes it in multiple places: 1. The original invocation, such as `bash script.sh test host 6379 password`, may be retained in the user's shell history. 2. The password is passed to `redis-cli` using `-a`, making it part of the child process's argument vector. Depending on operating-system process visibility and hardening settings, other local users or monitoring tools may inspect it while the command is running. 3. The command is assembled as a scalar string and executed through unquoted expansion. This causes shell word splitting and pathname expansion. Passwords, hostnames, or ports containing whitespace or glob characters may therefore be divided or expanded into unintended arguments. The use of `--no-auth-warning` only suppresses the warning emitted by `redis-cli`; it does not prevent credential disclosure. ### Attack Path 1. A user invokes the connection or monitoring feature with a Redis password: `bash script ...[truncated 1271 chars]
Remediation
## Remediation Suggestions 1. Stop accepting passwords as positional command-line arguments. Prompt interactively with input echo disabled or retrieve the secret from an appropriately protected secret manager or file descriptor: ```bash read -r -s -p "Redis password: " REDIS_PASSWORD echo ``` 2. Pass authentication through `REDISCLI_AUTH` rather than `redis-cli -a`, and remove it from the environment immediately after use: ```bash redis_cmd=(redis-cli -h "$host" -p "$port") if [[ -n "$REDIS_PASSWORD" ]]; then export REDISCLI_AUTH="$REDIS_PASSWORD" fi pong="$("${redis_cmd[@]}" PING 2>&1 || true)" unset REDISCLI_AUTH REDIS_PASSWORD ``` Environment variables can still be exposed in some environments, so a protected secret source and short variable lifetime remain important. 3. Construct commands using Bash arrays rather than scalar command strings. Arrays preserve argument boundaries and prevent word splitting and pathname expansion: ```bash redis_cmd=(redis-cli -h "$host" -p "$port") info="$("${redis_cmd[@]}" INFO server 2>&1 || true)" ``` 4. Validate the port as an integer in the valid TCP port range and reject control characters in endpoint input. 5. Update `SKILL.md` and usage output so examples do not encourage entering plaintext passwords directly on the command line. 6. Recommend Redis ACL users with only the commands and key patterns required for testing or monitoring, reducing the impact of any credential compromise.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Debian/Ubuntu
sudo apt install redis-tools

# macOS
brew install redis
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script accepts a Redis password as a positional CLI argument and then passes it via `redis-cli -a`, which exposes the secret to shell history, process listings, audit logs, and possibly other local users. This is especially risky in multi-user systems, CI environments, or when command invocations are logged.

Session Persistence

Medium
Category
Rogue Agent
Content
Return the type of a key: string, list, hash, set, zset, stream.

OBJECT ENCODING key
  Show internal encoding (e.g., ziplist, listpack, hashtable).

SCAN cursor [MATCH pattern] [COUNT n] [TYPE type]
  Iteratively scan all keys safely (preferred over KEYS in prod).
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if ! command -v redis-cli &>/dev/null; then
    echo -e "${YELLOW}⚠️  redis-cli not found.${RESET}"
    echo "Install with:"
    echo "  Ubuntu/Debian : sudo apt install redis-tools"
    echo "  macOS         : brew install redis"
    echo "  Alpine        : apk add redis"
    return 1
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if ! command -v redis-cli &>/dev/null; then
    echo -e "${YELLOW}⚠️  redis-cli not found.${RESET}"
    echo "Install with:"
    echo "  Ubuntu/Debian : sudo apt install redis-tools"
    echo "  macOS         : brew install redis"
    echo "  Alpine        : apk add redis"
    return 1
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Intent-Code Divergence

Low
Confidence
91% confidence
Finding
The header comments advertise a 'key monitor', which ordinarily implies observing ongoing key operations or changes. However, the implemented `monitor` command only runs `INFO keyspace`, `INFO memory`, and `DBSIZE` to print per-DB key counts and average TTLs, with no streaming or live monitoring behavior.

Static analysis

No suspicious patterns detected.