T09 · Insecure Skill Coding Practices
- Location
skill.md:16- Finding
Execution of an Unverified External Script and Unrestricted File Upload
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is meant to generate images with local ComfyUI and send them to Feishu, but it trusts a hard-coded local script path and uploads whatever file path that script prints.
Install only if you expect the skill to automatically send generated images to the current Feishu conversation. Before use, ensure the installed skill directory is protected from modification, verify draw.py is the reviewed script, and consider adding path containment so only generated image files from output_images can be uploaded.
skill.md:16Execution of an Unverified External Script and Unrestricted File Upload
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
ws.connect(f"ws://{SERVER_ADDRESS}/ws?clientId={CLIENT_ID}")
except:
log("错误: 无法连接 ComfyUI")
return
prompt_id = queue_prompt(prompt_workflow)['prompt_id']
log(f"任务已提交,等待 ComfyUI 生成...")
The function sends the workflow, including any injected custom_prompt text, to a local server via HTTP, and the script also opens a WebSocket connection. Although this may be part of the tool's purpose, this file does not explicitly disclose to the user that their prompt content is sent to another service process.
Request target host is built from a dynamic or untrusted value. If the host is attacker-influenced, this enables SSRF to arbitrary internal or metadata endpoints.
def queue_prompt(prompt):
p = {"prompt": prompt, "client_id": CLIENT_ID}
data = json.dumps(p).encode('utf-8')
req = urllib.request.Request(f"http://{SERVER_ADDRESS}/prompt", data=data)
return json.loads(urllib.request.urlopen(req).read())
def get_image(filename, subfolder, folder_type):
Request target host is built from a dynamic or untrusted value. If the host is attacker-influenced, this enables SSRF to arbitrary internal or metadata endpoints.
def get_image(filename, subfolder, folder_type):
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
url_values = urllib.parse.urlencode(data)
with urllib.request.urlopen(f"http://{SERVER_ADDRESS}/view?{url_values}") as response:
return response.read()
def run_workflow(custom_prompt=None):
The code saves generated image bytes to a local file in the output_images directory, which is a file write affecting the user's filesystem. While there is stderr logging for connection and progress, there is no explicit warning, confirmation, or comment disclosing that the skill will persist output files locally.
The skill is explicitly designed to generate content locally and immediately send it to the current Feishu chat or user, while also instructing the system to end silently and avoid any confirmation text. This removes user visibility and consent at the point of exfiltration or outbound messaging, increasing the risk of unintended content delivery, prompt leakage, or abuse if the skill is triggered in the wrong context.
The description is written to enforce a specific output behavior in Chinese context and does not offer the user any language or locale choice. Under the policy, forcing a specific language or locale without opt-in can be a natural-language policy violation unless clearly justified as region-specific.
This Python file contains all user-facing descriptions and printed output exclusively in Chinese, including behavior explanations and usage guidance. The audit policy flags language or locale constraints when a skill forces a specific language without offering user choice or clearly documenting a justified region-specific limitation.
This JSON manifest contains multiple user-facing titles in Chinese and a primary prompt at L064 written entirely in Chinese, indicating the skill is configured around a fixed language/locale. The file does not offer any user opt-in, alternative language selection, or justification for a Chinese-only constraint, which matches the language/locale policy violation criteria.
No suspicious patterns detected.