T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/setup.sh:46
- Finding
- Arbitrary Python Code Execution Through Unsafe String Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh`, lines 46–59 and 88–99 **Vulnerability Type**: Python code injection **Risk Level**: High ### Vulnerable Code Lines 46–59: ```bash # Build request body BODY=$(python3 -c " import json body = { 'daohao': '$DAOHAO', 'description': '$DESCRIPTION', } model = '$MODEL_HINT' skills = '$SKILLS' if model: body['model_hint'] = model if skills: body['skills'] = [s.strip() for s in skills.split(',')] print(json.dumps(body)) ") ``` Lines 88–99: ```bash # Save config mkdir -p "$CONFIG_DIR" python3 -c " import json config = { 'api_key': '$API_KEY', 'daohao': '$DAOHAO', 'base_url': '$BASE_URL', 'claim_code': '$CLAIM_CODE', 'linggen': '$LINGGEN' } with open('$CONFIG_FILE', 'w') as f: json.dump(config, f, indent=2, ensure_ascii=False) " ``` ### Technical Analysis The script interpolates shell variables directly into source code passed to `python3 -c`. These variables are not encoded or escaped as Python string data. Several values originate from environment variables, including `XIANAGENT_DAOHAO`, `XIANAGENT_DESC`, `XIANAGENT_MODEL`, `XIANAGENT_SKILLS`, and `XIANAGENT_URL`. Other values, such as `API_KEY`, `CLAIM_CODE`, and `LINGGEN`, originate in the remote registration response. A value containing quotes and a valid Python expression can escape its intended string context and cause Python code to execute. For example, an expression shaped like the following could execute a local command while preserving valid Python syntax when inserted as a dictionary value: ```text x' or __import__('os').system('attacker-command') or 'x ``` The vulnerability does not require shell metacharacter evaluation because the injected content is interpreted directly by the Python interpreter. ### Attack Path 1. An attacker controls an `XIANAGENT_*` environment variable through a malicious wrapper, automation configuration, inherited environment, or deployment template. Alternat ...[truncated 1420 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Never construct Python source by interpolating shell variables. Pass all values as arguments or environment data and let Python treat them strictly as strings. For request construction, use positional arguments: ```bash BODY=$(python3 - "$DAOHAO" "$DESCRIPTION" "$MODEL_HINT" "$SKILLS" <<'PY' import json import sys daohao, description, model, skills = sys.argv[1:] body = { "daohao": daohao, "description": description, } if model: body["model_hint"] = model if skills: body["skills"] = [item.strip() for item in skills.split(",")] print(json.dumps(body)) PY ) ``` Use the same pattern when writing the configuration: ```bash python3 - "$CONFIG_FILE" "$API_KEY" "$DAOHAO" "$BASE_URL" "$CLAIM_CODE" "$LINGGEN" <<'PY' import json import sys path, api_key, daohao, base_url, claim_code, linggen = sys.argv[1:] config = { "api_key": api_key, "daohao": daohao, "base_url": base_url, "claim_code": claim_code, "linggen": linggen, } with open(path, "w", encoding="utf-8") as output: json.dump(config, output, indent=2, ensure_ascii=False) PY ``` Additionally: - Validate the format and maximum length of environment-supplied identity fields. - Validate the registration response schema before using any fields. - Reject unexpected response types and excessively long values. - Create the configuration directory with restrictive permissions, such as mode `0700`. - Retain mode `0600` for the credential file. ]]>
