T09 · Insecure Skill Coding Practices
- Location
seedance_byteplus.py:232- Finding
Shell Command Injection Through Unsanitized Download Path
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This video-generation skill mostly does what it says, but it includes an avoidable local command-execution risk when downloaded videos are opened on macOS.
Install only if you are comfortable sending prompts and chosen images to BytePlus and, if used, sending generated videos through Feishu. Avoid using sensitive images or confidential prompts, keep ARK_API_KEY scoped and rotated, and do not use the macOS auto-open download path until the helper replaces os.system with a non-shell file-opening call.
seedance_byteplus.py:232Shell Command Injection Through Unsanitized Download Path
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
## Execution (Recommended: Python CLI Tool)
A Python CLI tool is provided at `~/.claude/skills/seedance-video-byteplus/seedance_byteplus.py` for robust execution with proper error handling, automatic polling, and local image base64 conversion. **Prefer using this tool over raw curl commands.**
### Quick Examples with Python CLI
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
With image URL:
TASK_RESULT=$(curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
With image URL:
TASK_RESULT=$(curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
With image URL:
TASK_RESULT=$(curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
With image URL:
TASK_RESULT=$(curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
With image URL:
TASK_RESULT=$(curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
echo "Waiting for video generation to complete..."
while true; do
STATUS_RESULT=$(curl -s -X GET "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks/${TASK_ID}" \
-H "Authorization: Bearer $ARK_API_KEY")
STATUS=$(echo "$STATUS_RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
curl -s -X GET "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks/${TASK_ID}" \
-H "Authorization: Bearer $ARK_API_KEY" | python3 -m json.tool
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
# List all tasks (paginated)
curl -s -X GET "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks?page_num=1&page_size=10" \
-H "Authorization: Bearer $ARK_API_KEY" | python3 -m json.tool
# Filter by status
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
-H "Authorization: Bearer $ARK_API_KEY" | python3 -m json.tool
curl -s -X GET "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks?page_num=1&page_size=10&filter.status=succeeded"
-H "Authorization: Bearer $ARK_API_KEY" | python3 -m json.tool
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
curl -s -X DELETE "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks/${TASK_ID}" \
-H "Authorization: Bearer $ARK_API_KEY"
This section documents a workflow that sends file content and metadata to an external messaging platform, which matches an exfiltration pattern because local data is intentionally moved off-host. While the feature appears product-intended rather than covertly malicious, in an agent environment it is still security-relevant because it enables outbound transfer of generated or arbitrary local files to a remote recipient.
[Video binary data]
**c) Send Message to Feishu Chat**
Automatically opening a downloaded file on macOS performs a local side effect unrelated to the minimum needed for video generation. Even aside from the shell issue, auto-launching content from a remote URL can expose users to unsafe file handling or unexpected execution chains through associated applications.
The code invokes a shell via os.system() using a path-derived string. Although the filename is internally constructed and task_id likely comes from the remote API, shell execution is unnecessary here and creates command-injection risk if the path or filename ever contains shell-significant characters or if future changes make filepath more user-controlled.
# Open on macOS
if sys.platform == "darwin":
os.system(f'open "{filepath}"')
except Exception as e:
print(f"Download failed: {e}", file=sys.stderr)
The README repeatedly instructs users to submit prompts, local images, and task metadata to the BytePlus Ark API, but it does not prominently warn that this content is transmitted to a third-party service. In a skill that encourages use of personal/local files and natural-language prompts, that omission can lead users to disclose sensitive data without informed consent.
The README directs users to store a long-lived API key in the shell environment, which can persist for the session and may be exposed to subprocesses, shell history workflows, debugging output, or multi-user environments if handled carelessly. While common practice, it increases the blast radius of credential leakage for a third-party paid API.
### 1. Get Your API Key
Sign up at [BytePlus ModelArk Console](https://console.byteplus.com/ark/region:ark+ap-southeast-1/apiKey) and create an API Key.
### 2. Set Environment Variable
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
Copy the skill folder to your Claude Code skills directory:
mkdir -p ~/.claude/skills/seedance-video-byteplus
# Copy SKILL.md and seedance_byteplus.py to the directory
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Generate a video from a text prompt with default settings (720p, 16:9, 5 seconds, with audio).
python3 ~/.claude/skills/seedance-video-byteplus/seedance_byteplus.py create \
--prompt "A golden retriever running through a field of sunflowers at sunset, cinematic lighting" \
--wait --download ~/Desktop
The curl example explicitly sends user prompts and authorization credentials to an external BytePlus endpoint, which is core functionality but still an external transmission risk. This becomes security-relevant because users may paste sensitive prompts or supply local/private images without a conspicuous warning about third-party transfer.
--wait --download ~/Desktop
**curl equivalent:**
```bash
curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
The skill declares no explicit tool scope even though it clearly expects access to environment variables, shell execution, and outbound network calls. Missing scope boundaries can cause an agent platform to grant broader capabilities than necessary and makes risky behaviors less visible to users and reviewers.
The skill does not clearly warn that prompts, task metadata, image URLs, and local image contents may be transmitted to BytePlus, nor that generated videos may be downloaded and opened locally. This creates a meaningful privacy and consent risk because users may provide sensitive prompts or files without understanding the external transfer and local execution side effects.
The skill is explicitly designed to send user prompts and possibly media to the external BytePlus API, so the transmission itself is expected. However, it remains a real security/privacy issue because the skill lacks strong disclosure and consent language around what data leaves the local environment.
## Execution (Recommended: Python CLI Tool)
A Python CLI tool is provided at `~/.claude/skills/seedance-video-byteplus/seedance_byteplus.py` for robust execution with proper error handling, automatic polling, and local image base64 conversion. **Prefer using this tool over raw curl commands.**
### Quick Examples with Python CLI
The workflow encourages creating, waiting for, downloading, and storing generated videos locally, which creates session persistence and residual data on disk. While expected for a file-generation skill, this becomes risky when the skill does not clearly communicate retention, storage location, or cleanup expectations.
# Text-to-video (create + wait + download)
python3 ~/.claude/skills/seedance-video-byteplus/seedance_byteplus.py create --prompt "A kitten yawning at the camera" --wait --download ~/Desktop
# Image-to-video from local file
This example sends prompt text and an image URL to an external BytePlus endpoint. In context that is the core function of the skill, but it still exposes user-supplied data to a third party and therefore requires clear notice and constrained execution.
With image URL:
TASK_RESULT=$(curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
This example converts a local image file to base64 and transmits the full file contents to the BytePlus API. That is more sensitive than a plain URL because it can exfiltrate local user data directly from disk to a third party if used on private images without informed consent.
IMG_BASE64=$(base64 < "$IMG_PATH" | tr -d '\n')
IMG_DATA_URL="data:image/${IMG_EXT_LOWER};base64,${IMG_BASE64}"
TASK_RESULT=$(curl -s -X POST "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
No suspicious patterns detected.