T09 · Insecure Skill Coding Practices
- Location
- site.js:103
- Finding
- Shell Command Injection Through Deployment Arguments<![CDATA[ ## Vulnerability Details **File Location**: `site.js:103-108` **Vulnerability Type**: OS command injection through user-controlled shell interpolation **Risk Level**: High ### Vulnerable Code ```js const env = { ...process.env, CLOUDFLARE_API_TOKEN: TOKEN, CLOUDFLARE_ACCOUNT_ID: ACCOUNT }; const result = execSync( `wrangler pages deploy "${dir}" --project-name "${projectName}" --branch main 2>&1`, { env } ).toString(); ``` ### Technical Analysis The positional arguments `dir` and `projectName` originate from command-line input and are interpolated directly into a command string passed to `execSync`. Because `execSync` executes string commands through a shell, enclosing these values in double quotes does not neutralize shell constructs such as command substitution. Embedded quotes can also terminate the intended argument and introduce additional commands. For example, a directory argument containing `$(touch /tmp/pwned)` would be evaluated by the shell even though it appears inside double quotes. The spawned shell also receives an environment containing the Cloudflare API token and account ID, increasing the consequences of successful command execution. ### Attack Path 1. An attacker persuades the Agent or user to deploy using an attacker-controlled directory or project-name argument. 2. The attacker includes shell syntax in the argument, such as command substitution or a quote-escape sequence. 3. `parseFlags` accepts the value without validation. 4. The value is interpolated into the command string. 5. `execSync` invokes a shell, which evaluates the injected syntax. 6. The attacker's command executes with the privileges and environment of the Skill process. ### Impact Assessment Successful exploitation permits arbitrary local command execution with the Agent's operating-system privileges. The injected process can read or modify files available to the Agent, invoke network tools, alter deployments, and access environment variables inherited ...[truncated 203 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Replace shell-string execution with `execFileSync` or `spawnSync` and pass arguments as an array: ```js const result = execFileSync( 'wrangler', ['pages', 'deploy', dir, '--project-name', projectName, '--branch', 'main'], { env, encoding: 'utf8', shell: false, } ); ``` - Validate `projectName` against the exact character and length restrictions accepted by Cloudflare Pages. - Resolve and validate `dir` as a local directory before invoking Wrangler. - Reject null bytes, control characters, and unexpected argument forms. - Limit the environment passed to the child process to only the variables Wrangler strictly requires. - Add regression tests using arguments containing `$()`, backticks, quotes, semicolons, newlines, and other shell metacharacters. ]]>
