T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/get_token.sh:23
- Finding
- Python Code Injection Through Unsafe Configuration Path Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/get_token.sh`, lines 23–42 **Vulnerability Type**: Environment-variable-driven Python code injection **Risk Level**: Medium ### Vulnerable Code ```bash CONFIG="${OPENCLAW_CONFIG:-$HOME/.openclaw/openclaw.json}" if [ -f "$CONFIG" ]; then echo "Reading credentials from $CONFIG (channels.lark.accounts.default)" >&2 APP_ID=$(python3 -c " import json, sys try: c = json.load(open('$CONFIG')) print(c['channels']['lark']['accounts']['default']['appId']) except (KeyError, FileNotFoundError): sys.exit(1) " 2>/dev/null) || true APP_SECRET=$(python3 -c " import json, sys try: c = json.load(open('$CONFIG')) print(c['channels']['lark']['accounts']['default']['appSecret']) except (KeyError, FileNotFoundError): sys.exit(1) " 2>/dev/null) || true fi ``` ### Technical Analysis The value of `OPENCLAW_CONFIG` is assigned to `CONFIG` and then interpolated directly into Python source passed to `python3 -c`. Although the shell variable is surrounded by single quotation marks in the generated Python expression, those quotation marks do not safely encode arbitrary path values. A configuration path containing a single quote and additional Python syntax can terminate the string passed to `open(...)` and inject attacker-controlled Python statements. The `[ -f "$CONFIG" ]` check limits exploitation to a value resolving to an existing file, but it does not make interpolation into executable Python source safe. On filesystems that permit quotation marks and other relevant characters in filenames, an attacker able to create a file and influence `OPENCLAW_CONFIG` can satisfy this condition. The vulnerable branch is reached when the caller does not provide both credentials through command-line arguments or environment variables. ### Attack Path 1. An attacker gains control over, or can influence, the `OPENCLAW_CONFIG` environment variable supplied to the helper. This could occur through a wrappe ...[truncated 1313 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Never interpolate a filesystem path into executable Python source. Pass the path as a positional argument: ```bash CREDENTIALS=$(python3 -c ' import json import sys with open(sys.argv[1], encoding="utf-8") as handle: config = json.load(handle) account = config["channels"]["lark"]["accounts"]["default"] print(account["appId"]) print(account["appSecret"]) ' "$CONFIG") ``` Additional hardening should include: 1. Parse both fields in one Python invocation to reduce complexity and duplicated attack surface. 2. Catch `json.JSONDecodeError`, `OSError`, `TypeError`, and `KeyError`, and return a clear error without exposing secrets. 3. Resolve and validate the configuration path where practical. 4. Reject configuration files that are writable by untrusted users. 5. Preserve shell quoting around `"$CONFIG"` whenever it is passed as an argument. 6. Add regression tests using paths containing quotes, spaces, newlines, backslashes, and shell metacharacters. ]]>
