T09 · Insecure Skill Coding Practices
- Location
scripts/video_gen.py:128- Finding
Unrestricted Output Path Allows Arbitrary File Overwrite
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to be a legitimate MiniMax video-generation helper, but it gives the script more file-write and runtime latitude than its documentation clearly scopes.
Install only if you are comfortable sending prompts, image URLs, and any face-reference images to MiniMax. Run it in a constrained workspace, avoid sensitive personal images unless you have consent, and do not pass arbitrary --output paths until the script restricts output to a dedicated directory and refuses overwrites.
scripts/video_gen.py:128Unrestricted Output Path Allows Arbitrary File Overwrite
scripts/video_gen.py:103Unbounded Network Requests, Polling, and Video Download
SKILL.md:17Unpinned Third-Party Dependency Installation
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
while True:
time.sleep(10)
response = requests.get(url, headers=HEADERS, params=params)
response.raise_for_status()
response_json = response.json()
status = response_json["status"]
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
while True:
time.sleep(10)
response = requests.get(url, headers=HEADERS, params=params)
response.raise_for_status()
response_json = response.json()
status = response_json["status"]
The skill documentation indicates capabilities that access environment variables and external network resources, but it does not declare any explicit tool scope or permission boundary. This weakens auditability and can cause the agent to use broader capabilities than reviewers or users expect, especially since the skill reads an API key and sends content to a third-party service.
The skill asks for prompts, image URLs, and face photos, but the description does not clearly warn that this data is transmitted to the external MiniMax API. This creates a privacy and consent risk, particularly for sensitive images like face photos, because users may provide data without understanding it leaves the local environment.
The instruction to automatically download generated video into the workspace and then send it to the user removes a human review checkpoint before data leaves the workspace. Even if the intended file is the generated video, automatic exfiltration patterns are dangerous because they normalize sending workspace-derived artifacts to users without verification of content, path, or accidental inclusion of sensitive material.
Multiple docstrings, status messages, and CLI help strings are presented only in Chinese, while the script itself does not provide any language selection or explain that it is intentionally Chinese-only. This creates a language-policy issue because users are forced into a specific locale without opt-in.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Subject-reference mode sends a face image reference to an external service without an explicit warning or consent checkpoint, even though face images may constitute sensitive biometric data. In a user-facing automation skill, this creates privacy and compliance risk because users may not realize such data is being transmitted off-platform.
While external transmission is generally expected for this skill, this particular mode involves subject-reference face imagery, which is materially more sensitive than ordinary prompts or generic images. Sending biometric-related data to a third party without explicit disclosure or consent increases privacy and regulatory risk beyond baseline expected transmission.
"duration": duration,
"resolution": resolution,
}
response = requests.post(url, headers=HEADERS, json=payload)
response.raise_for_status()
task_id = response.json()["task_id"]
return task_id
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
while True:
time.sleep(10)
response = requests.get(url, headers=HEADERS, params=params)
response.raise_for_status()
response_json = response.json()
status = response_json["status"]
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
while True:
time.sleep(10)
response = requests.get(url, headers=HEADERS, params=params)
response.raise_for_status()
response_json = response.json()
status = response_json["status"]
The code downloads a URL taken directly from a prior API response without validating the scheme, domain, or size of the response. If the upstream API were compromised, misconfigured, or returned an unexpected URL, this could trigger server-side request forgery-like behavior, unexpected outbound requests, or retrieval of malicious/oversized content.
print(f"正在下载视频到 {output_path}...")
with open(output_path, "wb") as f:
video_response = requests.get(download_url)
video_response.raise_for_status()
f.write(video_response.content)
print(f"视频已成功保存至 {output_path}")
The file presents core instructions and descriptions primarily in Chinese while some examples and labels are in English, but it does not tell users that the skill is intended for Chinese-speaking users or offer an alternate language option. This can violate a language/locale policy when a skill implicitly forces one language without user opt-in or justification.
No suspicious patterns detected.