T09 · Insecure Skill Coding Practices
- Location
build.sh:11- Finding
PowerShell Command Injection Through Unvalidated Version Input
- Content
View full analysis
/dev/null 2>&1 || command -v powershell >/dev/null 2>&1; then PSH="$(command -v powershell.exe 2>/dev/null || command -v powershell)" WIN_SRC="$(cygpath -w "$(pwd)/$(basename "$STAGE_DIR")" 2>/dev/null || echo "$(pwd)/$(basename "$STAGE_DIR")")" WIN_OUT="$(cygpath -w "$OUT_DIR/$ZIP_NAME" 2>/dev/null || echo "$OUT_DIR/$ZIP_NAME")" "$PSH" -NoProfile -Command "Compress-Archive -Path '${WIN_SRC}' -DestinationPath '${WIN_OUT}' -Force" fi ``` ### Technical Analysis The first positional argument is accepted as `VER` without validating that it is a valid semantic version. This value becomes part of `OUT_DIR`, `ZIP_NAME`, and ultimately `WIN_OUT`. Although Bash variable expansions are quoted, `WIN_OUT` is subsequently embedded directly into PowerShell source code passed through `-Command`. The value is surrounded by PowerShell single quotes, but embedded single-quote characters are not escaped. Consequently, an attacker-controlled version can terminate the `-DestinationPath` string and append arbitrary PowerShell statements. This is a code-versus-data separation failure. Bash quoting protects the initial shell invocation but does not make the resulting value safe for interpretation by the second command language. ### Attack Path 1. An attacker obtains the ability to influence the version argument supplied to `build.sh`, such as through a release parameter, CI input, or a developer copying an untrusted build ...[truncated 1394 chars]- Remediation
View remediation
&2 exit 1 fi ``` If prerelease and build metadata are not needed, use the narrower `^[0-9]+\.[0-9]+\.[0-9]+$` expression. 2. Do not concatenate untrusted data into PowerShell program text. Pass paths through environment variables or a parameterized script: ```bash WIN_SRC="$WIN_SRC" WIN_OUT="$WIN_OUT" \ "$PSH" -NoProfile -Command \ 'Compress-Archive -LiteralPath $env:WIN_SRC -DestinationPath $env:WIN_OUT -Force' ``` 3. Use `-LiteralPath` so wildcard characters in generated paths are not interpreted. 4. Apply the validation to both command-line and manifest-derived versions because repository content may also be attacker-controlled in a compromised pull request. 5. Add regression tests that reject versions containing quotes, semicolons, newlines, command substitutions, path separators, and PowerShell metacharacters. ]]>
