T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate-image.sh:345
- Finding
- Persistent Shell Command Injection Through Unsafe Configuration Serialization<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-image.sh:345-393` **Vulnerability Type**: Persistent shell command injection and plaintext credential storage **Risk Level**: High ### Vulnerable Code ```bash # Configure API Key if [ -z "${LISTENHUB_API_KEY:-}" ]; then echo "1. API Key" >&2 echo " Visit https://listenhub.ai/settings/api-keys" >&2 echo " (Requires subscription)" >&2 echo "" >&2 echo -n " Please paste your API key: " >&2 read -r api_key if [ -z "$api_key" ]; then echo "Error: API key cannot be empty" >&2 exit 1 fi # Check if config already exists (avoid duplicate append) if ! grep -q "^export LISTENHUB_API_KEY=" "$shell_rc" 2>/dev/null; then echo "export LISTENHUB_API_KEY=\"$api_key\"" >> "$shell_rc" else # If exists, replace sed_inplace "$shell_rc" "s|^export LISTENHUB_API_KEY=.*|export LISTENHUB_API_KEY=\"$api_key\"|" fi export LISTENHUB_API_KEY="$api_key" echo "" >&2 fi # Configure output path if [ -z "${LISTENHUB_OUTPUT_DIR:-}" ]; then echo "2. Output path" >&2 echo -n " Image save location (default: ~/Downloads): " >&2 read -r output_dir # Default to ~/Downloads if [ -z "$output_dir" ]; then output_dir="$HOME/Downloads" fi # Expand ~ symbol output_dir="${output_dir/#\~/$HOME}" # Create directory if not exists mkdir -p "$output_dir" # Check if config already exists (avoid duplicate append) if ! grep -q "^export LISTENHUB_OUTPUT_DIR=" "$shell_rc" 2>/dev/null; then echo "export LISTENHUB_OUTPUT_DIR=\"$output_dir\"" >> "$shell_rc" else sed_inplace "$shell_rc" "s|^export LISTENHUB_OUTPUT_DIR=.*|export LISTENHUB_OUTPUT_DIR=\"$output_dir\"|" fi export LISTENHUB_OUTPUT_DIR="$output_dir" echo "" >&2 fi ``` ### Technical Analysis The script reads an API key and output directory from standard input and interpolates those values directly into a shell startup file such as `.zshrc`, `.bashrc`, or `.profile`. Wrapping a valu ...[truncated 2484 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not store API keys in shell startup files. Use an operating-system credential store, such as macOS Keychain, Secret Service, or an appropriately secured application-specific configuration file. 2. If a local configuration file is used: - Create it with an owner-only mode such as `0600`. - Verify ownership before reading or modifying it. - Store data in a non-executable format such as JSON. 3. Validate API keys against the exact provider-defined format and length. Reject quotes, newlines, carriage returns, NUL bytes, and unexpected control characters. 4. Canonicalize and validate output directories separately. Do not serialize them as executable shell source. 5. If shell assignment persistence is unavoidable, use a robust shell serializer such as `printf '%q'` rather than manual quoting. 6. Do not place untrusted values directly in `sed` expressions. Prefer reconstructing a configuration file through a safe parser and atomic replacement. 7. Write updates to a securely created temporary file, set restrictive permissions, and atomically rename it into place. 8. Avoid automatically modifying `.zshrc`, `.bashrc`, `.bash_profile`, or `.profile`; instead, print an explicit opt-in setup command after safely escaping its value. ]]>
