T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/setup.sh:347
- Finding
- Root Command Execution Through Unsafe API-Key Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:347-357` **Vulnerability Type**: Python source injection from attacker-controlled configuration **Risk Level**: Critical ### Vulnerable Code ```bash CONFIG_FILE="$SKILL_DIR/config.json" python3 -c " import json c = {} el = '${ELEVENLABS_API_KEY:-}' oa = '${OPENAI_API_KEY:-}' dg = '${DEEPGRAM_API_KEY:-}' if el: c['ELEVENLABS_API_KEY'] = el if oa: c['OPENAI_API_KEY'] = oa if dg: c['DEEPGRAM_API_KEY'] = dg json.dump(c, open('$CONFIG_FILE', 'w'), indent=2) " ``` ### Technical Analysis The setup script runs as root and directly interpolates provider API-key values into Python source passed to `python3 -c`. These values may originate from interactive prompts, inherited environment variables, an existing configuration file, or a legacy service file. Shell variables are not safely encoded as Python string literals. A value containing a quote, statement separator, and Python expression can terminate the intended string and inject arbitrary Python statements. For example, a value shaped like: ```text '; __import__("os").system("ATTACKER_COMMAND"); # ``` would cause attacker-controlled Python to execute while setup is running with root privileges. ### Attack Path 1. An attacker controls or influences a provider API-key value supplied to the setup script. 2. The administrator runs `sudo bash scripts/setup.sh`. 3. The crafted value is inserted into the `python3 -c` source without escaping. 4. The value terminates the intended Python string and introduces an additional statement. 5. Python executes the injected statement as root. 6. The attacker can modify system files, create privileged accounts, install persistence, or extract credentials. ### Impact Assessment Successful exploitation provides arbitrary command execution as root. The resulting compromise is system-wide and can affect all users, system services, OpenClaw credentials, provider API keys, and stored conversation data. ]]>
- Remediation
- <![CDATA[ ## Remediation Suggestions - Never generate Python source by interpolating untrusted values. - Pass values through environment variables and read them with `os.environ`. - Alternatively, pass values as positional arguments and consume them through `sys.argv`. - Serialize the complete configuration using a fixed Python program rather than `python3 -c`. - Validate expected API-key formats, while treating validation only as defense in depth. - Add regression tests using quotes, newlines, semicolons, and Python syntax in every configurable value. A safer pattern is: ```bash export ELEVENLABS_API_KEY OPENAI_API_KEY DEEPGRAM_API_KEY CONFIG_FILE python3 <<'PY' import json import os config = {} for key in ("ELEVENLABS_API_KEY", "OPENAI_API_KEY", "DEEPGRAM_API_KEY"): value = os.environ.get(key, "") if value: config[key] = value with open(os.environ["CONFIG_FILE"], "w", encoding="utf-8") as handle: json.dump(config, handle, indent=2) PY ``` ]]>
