T09 · Insecure Skill Coding Practices
- Location
scripts/run_blender.sh:3- Finding
Unrestricted Python Execution Through Caller-Controlled Blender Script Path
- Content
View full analysis
Vulnerability Details
File Location:
scripts/run_blender.sh:3-5
Related Documentation:SKILL.md:47-58,SKILL.md:69-81
Vulnerability Type: Unrestricted execution of generated Python code and insufficient input validation
Risk Level: HighVulnerable Code
bash SCRIPT_PATH=$1 blender -b -P $SCRIPT_PATH --render-output /tmp/output --render-format FFMPEG --render-animTechnical Analysis
The runner accepts an arbitrary script path from its first argument and supplies it to Blender's
-Poption. This option executes the selected file as ordinary Python with the permissions of the Blender process.The runner does not:
- Restrict execution to the documented
/tmp/blender_script.pypath. - Confirm that the path resolves to an approved regular file.
- Reject symbolic links or paths outside the intended temporary directory.
- Validate the Python program against an allowlist of Blender scene operations.
- Restrict Python imports, subprocess creation, filesystem access, or network access.
- Enforce the documented animation duration or resource limits.
- Quote
"$SCRIPT_PATH", leaving it subject to shell word splitting and pathname expansion.
Consequently, statements in
SKILL.mdthat scripts are limited to Blender operations, cannot access sensitive directories, and should not perform arbitrary system actions are policy guidance only; the implementation does not enforce them. Blender Python can import modules such asos,subprocess,socket, orpathlib, allowing behavior unrelated to rendering.Attack Path
- An attacker submits an animation request containing instructions that influence the generated Blender Python program, or causes an untrusted existing script path to be passed to the runner.
- The agent writes the attacker-influenced Python code to a file or invokes
run_blender.shwith the attacker-selected path. - The runner passes that path directly to ` ...[truncated 1108 chars]
- Restrict execution to the documented
- Remediation
View remediation
Remediation Suggestions
- Execute Blender in a dedicated container or equivalent sandbox using an unprivileged UID, no Linux capabilities, no host networking, a read-only root filesystem, and narrowly scoped writable mounts.
- Apply CPU, memory, process-count, output-size, and wall-clock limits. Terminate rendering when the approved duration or execution deadline is exceeded.
- Remove the caller-controlled path or require one canonical script location. Resolve the path with
realpath, verify that it equals the approved path, require a regular file owned by the expected user, and reject symbolic links. - Quote all shell expansions and enable strict shell behavior, for example:
bash #!/bin/bash set -euo pipefail readonly SCRIPT_PATH="/tmp/blender_script.py" [[ -f "$SCRIPT_PATH" && ! -L "$SCRIPT_PATH" ]] || { echo "Invalid Blender script" >&2 exit 1 } blender -b -P "$SCRIPT_PATH" \ --render-output /tmp/output \ --render-format FFMPEG \ --render-anim- Prefer a constrained scene-description format and a trusted renderer implementation over executing generated Python. If Python remains necessary, parse and validate its abstract syntax tree against a strict allowlist and reject filesystem, networking, subprocess, dynamic import, and dynamic evaluation functionality.
- Mount only the approved input and output directories into the sandbox. Do not expose home directories, credential stores, host sockets, or sensitive environment variables.
- Verify that
/tmp/output.mp4was actually produced and return Blender's real exit status instead of printing an unconditional success message.
