T09 · Insecure Skill Coding Practices
Error
- Location
- setup-secure.sh:139
- Finding
- Arbitrary Python Code Execution Through Unsafe Configuration Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `setup-secure.sh`, lines 139-156 **Vulnerability Type**: Untrusted input embedded into generated Python source **Risk Level**: High ### Vulnerable Code ```bash python3 << EOF import json from pathlib import Path import os config_file = Path("$CONFIG_FILE") # Attempt to read existing configuration if config_file.exists(): config = json.load(open(config_file)) else: config = { 'paramNames': [], 'defaultParams': {} } # Update configuration config['url'] = "$WEBHOOK_URL" config['key'] = '' ``` The value assigned to `WEBHOOK_URL` originates from interactive input or an existing configuration: ```bash read -p "Enter the new Webhook URL: " WEBHOOK_URL ``` ### Technical Analysis The script expands `WEBHOOK_URL` directly into Python source code executed through a heredoc. The value is not serialized, escaped, or passed as data. A value containing quotation marks and Python statements can terminate the intended string literal and inject additional Python code. For example, a malicious URL value shaped like the following can alter the generated Python program: ```text "; __import__('os').system('touch /tmp/setup-code-executed'); injected=" ``` The resulting Python source contains an attacker-controlled call to `os.system()`. The issue is Python source injection rather than recursive shell command substitution: shell metacharacters inside a variable are not automatically reevaluated, but Python syntax inserted into the heredoc is parsed and executed by the Python interpreter. The same risk applies when `WEBHOOK_URL` is loaded from an existing `config.json`, meaning a tampered configuration can trigger execution when the user later runs the setup script. ### Attack Path 1. An attacker supplies a crafted webhook URL through setup instructions, a copied configuration, or a modified `config.json`. 2. The user invokes `./setup-secure.sh`. 3. The script stores the crafted value in `WE ...[truncated 838 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Do not embed configuration values into generated Python source. Pass them as environment variables or command-line arguments and read them as data. A safer pattern is: ```bash CONFIG_FILE="$CONFIG_FILE" WEBHOOK_URL="$WEBHOOK_URL" python3 <<'EOF' import json import os from pathlib import Path config_file = Path(os.environ["CONFIG_FILE"]) webhook_url = os.environ["WEBHOOK_URL"] if config_file.exists(): with config_file.open("r", encoding="utf-8") as handle: config = json.load(handle) else: config = { "paramNames": [], "defaultParams": {} } config["url"] = webhook_url config["key"] = "" with config_file.open("w", encoding="utf-8") as handle: json.dump(config, handle, ensure_ascii=False, indent=2) os.chmod(config_file, 0o600) EOF ``` Additional hardening should include: 1. Quote the heredoc delimiter to prevent shell expansion inside the Python program. 2. Validate that webhook URLs use an expected scheme, preferably HTTPS. 3. Optionally restrict the hostname to documented Octoparse domains where compatible with legitimate deployments. 4. Never construct executable source code through string interpolation. 5. Add regression tests using URLs containing quotes, semicolons, backslashes, Unicode characters, and newlines. ]]>
