T09 · Insecure Skill Coding Practices
- Location
scripts/run-playwright-docker.sh:14- Finding
Shell Command Injection Through the Playwright Test Filter
- Content
View full analysis
Vulnerability Details
File Location:
scripts/run-playwright-docker.sh, lines 14–16 and 27
Vulnerability Type: OS command injection through unsafe shell-string construction
Risk Level: HighVulnerable Code
bash GREP_ARG="" if [[ -n "$FILTER" ]]; then GREP_ARG="--grep '$FILTER'" fi echo "[run][docker] 镜像: $IMAGE" echo "[run][docker] 输出目录: $OUT_DIR" docker run --rm -t \ -v "$PWD":/work \ -w /work \ "$IMAGE" \ bash -lc "npm ci || npm i; npx playwright test --reporter=line,html --output='$OUT_DIR' $GREP_ARG" | tee "$OUT_DIR/run.log"Technical Analysis
The user-controlled
FILTERargument is interpolated intoGREP_ARGand subsequently inserted into a command string executed bybash -lc. Wrapping the value in single quotes does not provide protection because an attacker can include another single quote in the input, terminate the intended quoted context, and append additional shell commands.The local runner correctly uses a Bash array, but the Docker runner converts the filter back into shell syntax. The Docker container also mounts the current project directory read-write at
/work, so an injected command can modify or delete repository content and generated artifacts.Attack Path
-
An attacker obtains the ability to control the test filter supplied to the Docker runner, directly or through
run-playwright-auto.sh. -
The attacker provides a filter containing shell metacharacters, for example:
bash ./scripts/run-playwright-docker.sh "'; touch /work/pwned; #" -
The script constructs a command equivalent to:
bash npx playwright test ... --grep ''; touch /work/pwned; #' -
bash -lcparses the injected semicolon as a command separator. -
The injected command executes inside the Playwright container with write access to the mounted project directory.
More destructive payloads could overwrite tests, source ...[truncated 665 chars]
-
- Remediation
View remediation
Remediation Suggestions
-
Do not concatenate the filter into a command interpreted by
bash -lc. -
Pass the filter as a positional argument to a fixed shell program, preserving it as data:
bash docker run --rm -t \ -v "$PWD":/work \ -w /work \ "$IMAGE" \ bash -c 'npm ci && npx playwright test --reporter=line,html --output="$1" --grep "$2"' \ _ "$OUT_DIR" "$FILTER" -
Handle the empty-filter case separately so that
--grepis omitted rather than passed an empty value. -
Prefer an entrypoint script that constructs and executes a command array without additional shell evaluation.
-
Mount project source read-only where practical and mount only the results directory as writable.
-
Disable container network access with
--network=nonewhen tests do not require it. -
Add regression tests containing single quotes, semicolons, command substitutions, spaces, and newline characters in the filter.
-
