T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:73
- Finding
- Command Injection Through Unquoted Trace and Project Identifiers<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 73–89 **Vulnerability Type**: OS command injection caused by direct interpolation of attacker-controlled identifiers **Risk Level**: High ### Vulnerable Code ```bash python3 /Users/jialize/.codewiz/skills/xray-ai-trace-analysis/scripts/query_langfuse_trace.py --save_project_id <project_id> --trace_id <trace_id> ``` ```bash python3 /Users/jialize/.codewiz/skills/xray-ai-trace-analysis/scripts/query_langfuse_trace.py --trace_id <trace_id> ``` ```bash python3 /Users/jialize/.codewiz/skills/xray-ai-trace-analysis/scripts/query_langfuse_trace.py --trace_id <trace_id> --env sit ``` ### Technical Analysis The skill directs the agent to extract `project_id` and `trace_id` from user-provided URLs or messages and substitute them directly into shell command templates. It does not require validation, shell escaping, quoting, or invocation through an argument-array API. If the agent constructs and executes these commands through a shell, an attacker can supply identifiers containing shell metacharacters such as `;`, `&&`, command substitutions, redirections, or newline characters. The shell may interpret those characters as additional commands rather than as part of a trace identifier. The `--save_project_id` variant also passes attacker-controlled data into a persistent project-ID storage operation. This is not independently proven to enable arbitrary persistent instructions because the referenced script was not included in the audited project, but it increases the importance of strict input validation. The hardcoded absolute path is also environment-specific and places trust in an external local script outside the reviewed skill package. No evidence established that this script is malicious, modified, or downloaded remotely. ### Attack Path 1. An attacker provides a crafted trace URL or identifier, for example an input conceptually equivalent to: ```text legitimate-trace-id; attacker- ...[truncated 1835 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Never assemble a shell command by interpolating user-controlled identifiers. Invoke the script through a subprocess API using a fixed argument array and disable shell processing: ```python subprocess.run( [ "python3", trusted_script_path, "--trace_id", validated_trace_id, ], shell=False, check=True, ) ``` 2. Apply strict allow-list validation before execution. If Langfuse identifiers are UUIDs, require canonical UUID syntax. Otherwise, define the narrowest documented identifier grammar, such as: ```regex \A[A-Za-z0-9_-]{1,128}\z ``` Reject whitespace, control characters, path separators, shell metacharacters, and unexpected URL-decoded characters. 3. Parse supplied URLs with a standard URL parser. Extract only the expected path segments and reject malformed, duplicate, decoded, or ambiguous parameters. 4. Update `SKILL.md` to explicitly prohibit shell-string execution and require structured argument passing. Quoting alone should not be treated as the primary defense. 5. Validate `project_id` before invoking `--save_project_id`. Store it as inert data in a narrowly scoped configuration file with restrictive permissions, and never later reinterpret it as code or a command fragment. 6. Replace the user-specific absolute script path with a package-controlled, verified path. Confirm the referenced script's ownership and integrity before execution. 7. Run trace analysis under a least-privileged account with minimal filesystem access, restricted environment variables, and network access limited to the required XRay/Langfuse endpoints. 8. Add regression tests using semicolons, command substitutions, newlines, redirections, encoded metacharacters, and oversized identifiers to verify that every malicious input is rejected and never reaches a shell interpreter. ]]>
