T09 · Insecure Skill Coding Practices
- Location
scripts/switch_tts_voice.sh:4- Finding
ElevenLabs API Key Exposed Through Command-Line Arguments
- Content
View full analysis
Vulnerability Details
File Location:
scripts/switch_tts_voice.sh, lines 4-12
Related Documentation:SKILL.md, lines 47-50
Vulnerability Type: Sensitive credential exposure through command-line arguments
Risk Level: MediumVulnerable code:
bash if [[ $# -lt 1 || $# -gt 4 ]]; then echo "usage: $0 <voiceId> [languageCode] [modelId] [apiKey]" >&2 exit 1 fi VOICE_ID="$1" LANGUAGE_CODE="${2:-zh}" MODEL_ID="${3:-eleven_multilingual_v2}" API_KEY="${4:-}"Documented invocation:
bash bash scripts/switch_tts_voice.sh "<voiceId>" bash scripts/switch_tts_voice.sh "<voiceId>" "<languageCode>" bash scripts/switch_tts_voice.sh "<voiceId>" "<languageCode>" "<modelId>" bash scripts/switch_tts_voice.sh "<voiceId>" "<languageCode>" "<modelId>" "<apiKey>"Credential processing code (
scripts/switch_tts_voice.sh, lines 24-36):bash jq --arg voiceId "$VOICE_ID" --arg languageCode "$LANGUAGE_CODE" --arg modelId "$MODEL_ID" --arg apiKey "$API_KEY" ' .messages.tts as $existingTts | .messages.tts = { "auto": (($existingTts.auto // "always")), "provider": "elevenlabs", "elevenlabs": ( ($existingTts.elevenlabs // {}) + { "modelId": $modelId, "languageCode": $languageCode, "voiceId": $voiceId } + (if ($apiKey | length) > 0 then {"apiKey": $apiKey} else {} end) ) }Technical Analysis
The script accepts a long-lived ElevenLabs API key as its fourth positional argument, and the skill documentation explicitly instructs users to invoke it that way. Shell quoting prevents metacharacter interpretation but does not provide confidentiality.
Secrets supplied on a command line may be retained in shell history, terminal-session recordings, audit logs, support bundles, or command telemetry. They may also ...[truncated 1446 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove the API key from the positional-argument interface and usage text.
- Prefer the API key already stored in the protected OpenClaw configuration or obtain it from a dedicated secret manager.
- For interactive configuration, read the value without echoing:
bash read -rs -p "ElevenLabs API key: " API_KEY printf '\n' >&2 - If standard input is used, clearly document that callers must not place the secret directly in the shell command.
- When environment-based injection is necessary, use a secret-management facility and ensure the environment is not captured by debugging or telemetry systems.
- Pass sensitive data to
jqthrough a protected temporary input or inherited file descriptor rather than--arg, because--argplaces the value in the child process's command-line arguments. - Update
SKILL.mdso no example demonstrates passing credentials on a command line. - Advise existing users who followed the documented command to remove affected history entries and rotate the exposed API key.
- Ensure
~/.openclaw/openclaw.jsonand backups containing credentials have restrictive permissions, such as mode0600.
