T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/agents/hermes.sh:44
- Finding
- Persistent Code Execution Through Unsafe Endpoint Interpolation<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/integrate.sh:19-23` - `scripts/agents/hermes.sh:44-66` - `scripts/agents/workswarm.sh:171-180,246` - `scripts/agents/openclaw.sh:124-126,203-205,281` - `scripts/agents/kimicode.sh:22-53,113` **Vulnerability Type**: Persistent shell and generated-code injection **Risk Level**: High ### Vulnerable Code The command-line endpoint is accepted without syntax or scheme validation: ```bash while [[ $# -gt 0 ]]; do case "$1" in --agent) AGENT="$2"; shift 2 ;; --all) ALL_AGENTS=true; shift ;; --endpoint) OV_ENDPOINT="$2"; OV_MCP_URL="${OV_ENDPOINT}/mcp"; shift 2 ;; --api-key) OV_API_KEY="$2"; shift 2 ;; ``` Hermes embeds the endpoint directly into a persistent shell script: ```bash "$OV_PY" - "$tpl" "$OV_ENDPOINT" "$OV_SHARED_DIR" <<'PYTPL' import sys, os, re tpl_path = sys.argv[1] endpoint = sys.argv[2] shared_dir = sys.argv[3] with open(tpl_path) as f: tpl = f.read() block = """ # ── OpenViking memory provider (added by huawei-cloud-openviking-agent-integration skill) ── # Re-injects memory.provider after model config is written on each start. if ! grep -q "provider: openviking" "$HOME/.hermes/config.yaml" 2>/dev/null; then cat >> "$HOME/.hermes/config.yaml" << 'OVYAML' memory: provider: openviking openviking: endpoint: __OV_ENDPOINT__ OVYAML fi if ! grep -q "OPENVIKING_ENDPOINT" "$HOME/.hermes/.env" 2>/dev/null; then echo "OPENVIKING_ENDPOINT='__OV_ENDPOINT__'" >> "$HOME/.hermes/.env" fi """ block = block.replace("__OV_ENDPOINT__", endpoint) ``` WorkSwarm similarly interpolates the endpoint into an exported shell variable: ```bash "$OV_PY" - "$tpl" "$OV_ENDPOINT" "$OV_MCP_URL" "$_agents_tmp" "$OV_SHARED_DIR" "$OV_TEMPLATE_DIR" "$OV_RUNTIME_DIR" <<'PYTPL' import sys, os path, endpoint, mcp_url, agents_md_path, shared_dir, template_dir, runtime_dir = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7] with open(path) as f: lines ...[truncated 4291 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the endpoint with a strict URL parser before any network request or file modification. 2. Permit only `http` and `https` schemes. 3. Permit plaintext HTTP only for loopback addresses unless the user explicitly approves the risk. 4. Reject control characters, newlines, shell metacharacters, quotes, backticks, and command-substitution syntax. 5. Do not construct executable code through `str.replace()` or Python `%` formatting. 6. For shell output, generate assignments with a proven shell-escaping routine such as Bash `printf '%q'`. 7. Prefer passing endpoint values through environment variables or positional arguments rather than embedding them into generated scripts. 8. Use `json.dump()` or `json.dumps()` when generating JSON or Python-compatible string values. 9. Use a YAML serializer when writing YAML configuration. 10. Validate generated files with `bash -n`, JSON parsing, or YAML parsing before replacing persistent templates. 11. Write changes to a temporary file, validate them, and atomically rename them into place. 12. Add tests covering quotes, backticks, `$()`, semicolons, newlines, Unicode control characters, and malformed URLs. ]]>
