T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:25
- Finding
- Python Code Injection Through the AGENT_NAME Environment Variable<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:25-55` **Vulnerability Type**: Python source-code injection through unsafe string interpolation **Risk Level**: High ### Vulnerable Code ```bash get_feishu_creds() { local agent_name="${AGENT_NAME:-main}" local config_file="$HOME/.openclaw/openclaw.json" local app_id app_secret # Attempt to read the current agent's account app_id=$(python3 -c " import json, sys c = json.load(open('$config_file')) accounts = c.get('channels', {}).get('feishu', {}).get('accounts', {}) # First attempt the agent name if '$agent_name' in accounts: print(accounts['$agent_name'].get('appId', '')) elif 'main' in accounts: print(accounts['main'].get('appId', '')) else: print('') " 2>/dev/null) app_secret=$(python3 -c " import json, sys c = json.load(open('$config_file')) accounts = c.get('channels', {}).get('feishu', {}).get('accounts', {}) if '$agent_name' in accounts: print(accounts['$agent_name'].get('appSecret', '')) elif 'main' in accounts: print(accounts['main'].get('appSecret', '')) else: print('') " 2>/dev/null) echo "$app_id $app_secret" } ``` ### Technical Analysis The environment-controlled `AGENT_NAME` value is expanded by the shell directly into two Python programs passed to `python3 -c`. The value is placed inside Python string literals without any escaping or validation: ```python if '$agent_name' in accounts: ``` An attacker who can control `AGENT_NAME` can supply quote characters, line breaks, and Python statements that terminate the intended string and alter the generated program. The resulting statements are evaluated by `python3` with the same operating-system privileges and environment as the agent. This is not limited to selecting another Feishu account. Successful injection can invoke Python modules such as `os` or `subprocess`, read local files, modify files accessible to the agent, or start arbitrary commands. The code is executed twice be ...[truncated 1517 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Never interpolate environment variables or other runtime input into Python source passed through `python3 -c`. - Pass the configuration path and agent name as positional arguments: ```bash app_id=$(python3 - "$config_file" "$agent_name" <<'PY' import json import sys config_file = sys.argv[1] agent_name = sys.argv[2] with open(config_file, encoding="utf-8") as handle: config = json.load(handle) accounts = config.get("channels", {}).get("feishu", {}).get("accounts", {}) account = accounts.get(agent_name) if account is None: raise SystemExit(f"Unknown Feishu account: {agent_name}") print(account.get("appId", "")) PY ) ``` - Apply the same parameterized design when retrieving `appSecret`. - Prefer one Python invocation that returns structured output instead of duplicating credential lookup logic. - Validate `AGENT_NAME` against an explicit allowlist of configured account names. - Reject control characters, line breaks, and unexpected account-name syntax as defense in depth. - Stop execution on lookup or parsing errors instead of suppressing all diagnostic output. - Avoid exposing application secrets in command output or logs; use a protected inter-process mechanism or perform token acquisition inside the same process where practical. ]]>
