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.
