T09 · Insecure Skill Coding Practices
- Location
skill.py:215- Finding
Unrestricted Remote Media Fetching Enables SSRF and External Data Relay
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is for Wuli image and video generation, but it has review-worthy network, file-opening, and undeclared cookie behavior.
Review before installing. Use only with non-sensitive media and trusted URLs, run it in a network-restricted environment if possible, unset WULI_EXTRA_COOKIE unless explicitly needed, and be aware that generated files may be saved locally and opened automatically.
skill.py:215Unrestricted Remote Media Fetching Enables SSRF and External Data Relay
skill.py:154Undeclared Environment Cookie Is Silently Transmitted to Wuli API
skill.py:287Network-Downloaded Results Are Automatically Opened Without Content Validation
File contents flow to a network sink. This may indicate data exfiltration of sensitive files.
file_data = path.read_bytes()
put_req = urllib.request.Request(upload_url, data=file_data, method="PUT")
put_req.add_header("Content-Type", "application/octet-stream")
with urllib.request.urlopen(put_req, timeout=120) as _:
pass
width, height = get_image_size(file_data)
The skill downloads arbitrary remote content from user-supplied URLs and then re-uploads it to Wuli storage, effectively acting as a generic fetch-and-forward network relay. In an agent environment, this expands capability beyond image/video generation and can be abused to access internal resources or transfer sensitive content via SSRF-style retrieval.
put_req = urllib.request.Request(upload_url, data=media_data, method="PUT")
put_req.add_header("Content-Type", "application/octet-stream")
with urllib.request.urlopen(put_req, timeout=120) as _:
pass
width, height = get_image_size(media_data)
The skill advertises and documents capabilities that involve environment access, local file reads/writes, network operations, and shell execution, but it does not declare any explicit tool scope or permissions boundary. This increases the chance that an agent runtime may invoke the skill with broader capabilities than users expect, enabling uploads, downloads, and local execution effects without clear consent or confinement.
The trigger phrase 'edit image' overlaps with a common built-in verb pattern and can shadow or hijack ordinary user requests that are not meant for this external skill. If auto-selected, the skill could route user images and prompts to a third-party API, causing unexpected disclosure, charges, and file operations.
The trigger phrase 'create artwork' is highly generic and conflicts with common creation intents, making accidental invocation plausible. In this skill's context, accidental invocation is more dangerous because the skill performs external network requests, may upload media, and can auto-download/open outputs.
The trigger list includes broad generic phrases like 'generate image', 'generate video', 'edit image', and 'create artwork', which can match many unrelated user requests. Over-broad triggers can cause the agent to select this skill unexpectedly, leading to unintended API calls, media uploads, costs, or disclosure of user-provided files to a third-party service.
The documentation states that local files may be auto-uploaded, remote URLs may be fetched and re-uploaded, results are auto-downloaded, and outputs may be auto-opened, but it does not prominently warn about privacy, bandwidth, storage, or local system side effects. Users may unknowingly send sensitive media to an external platform or trigger local file creation/opening behavior they did not intend.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
"default": "true"
},
"no_optimize": {
"description": "Disable prompt optimization when you need the raw prompt sent as-is.",
"default": "false"
}
}
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
"default": "true"
},
"no_optimize": {
"description": "Disable prompt optimization when you need the raw prompt sent as-is.",
"default": "false"
}
}
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
"default": "true"
},
"no_optimize": {
"description": "Disable prompt optimization when you need the raw prompt sent as-is.",
"default": "false"
}
}
The documentation shows a bearer token directly in example headers and code without an explicit warning to use placeholders only and never paste real secrets into shared logs, screenshots, or source files. Even if the token string appears illustrative, this pattern normalizes unsafe secret handling and can lead users or downstream tool builders to hardcode or expose live API credentials.
The upload examples instruct users to download third-party media and re-upload local or remote files to Wuli OSS, but do not clearly warn that this transmits potentially sensitive content to an external service. In a skill context, this can cause accidental disclosure of private images, videos, or copyrighted material because the examples encourage transfer as a normal preprocessing step.
This example performs an explicit external upload of a local file to a presigned URL, which is a real data egress action. In this skill's domain, external transmission is expected functionality, but it is still security-relevant because local user content may be uploaded off-device without adequate privacy notice, validation, or user confirmation.
UPLOAD_URL=$(echo $UPLOAD_RESP | jq -r '.data.uploadUrl')
# 2. PUT 上传文件(Content-Type 必须为 application/octet-stream)
curl -X PUT \
-H "Content-Type: application/octet-stream" \
--data-binary @photo.jpg \
"$UPLOAD_URL"
This example uploads a local video file to an external presigned URL, creating a direct path for outbound transfer of potentially sensitive media. While consistent with the API's intended use, the lack of adjacent warnings makes accidental disclosure more likely, especially for agent users who may not realize local assets are being copied to third-party infrastructure.
UPLOAD_URL=$(echo $UPLOAD_RESP | jq -r '.data.uploadUrl')
curl -X PUT \
-H "Content-Type: application/octet-stream" \
--data-binary @clip.mp4 \
"$UPLOAD_URL"
Accepting arbitrary remote URLs and fetching them directly gives the skill broad URL-retrieval behavior unrelated to the narrow intent of generation. In a local or enterprise agent context, this can be abused for SSRF-like access to internal services, metadata endpoints, or as a blind content transfer mechanism.
The skill performs significant side effects—fetching remote URLs, writing files locally, and opening them—without an explicit user warning or separate consent step. In agent settings, hidden side effects reduce user awareness and can turn normal media prompts into unexpected network access and local file/application activity.
Automatically opening downloaded files is unrelated to the stated purpose of generating media and introduces a local side effect that can activate external applications on untrusted content. That increases the attack surface substantially, especially on systems where handlers may execute scripts, render active content, or expose parser vulnerabilities.
The skill automatically launches downloaded files with the OS default handler via open, which creates an unintended local code/content execution surface. Although the call is not shell-invoked, opening attacker-controlled downloaded content can trigger risky applications, browser handlers, or vulnerable previewers without explicit user consent.
system = platform.system()
try:
if system == "Darwin":
subprocess.Popen(["open", filepath])
elif system == "Windows":
os.startfile(filepath)
elif system == "Linux":
The Linux xdg-open invocation automatically hands downloaded content to the desktop's default application, which is outside the core image/video generation function. Even without shell injection, this can expose users to malicious files, browser-based handlers, or unsafe helper applications processing untrusted output.
elif system == "Windows":
os.startfile(filepath)
elif system == "Linux":
subprocess.Popen(["xdg-open", filepath])
except Exception:
pass
The file’s user-facing text and link descriptions are entirely in Chinese, which can amount to forcing a specific language for users without opt-in. The policy allows locale constraints when they are explicitly justified, but this README does not state that the skill is intended only for Chinese-speaking or region-specific users.
The token setup error message contains the Chinese-only phrase "左下角 -> API 开放平台" embedded in otherwise English guidance. This imposes a locale-specific instruction without giving the user a language choice or documenting that the skill is intentionally region/language-specific.