T09 · Insecure Skill Coding Practices
- Location
scripts/happyhorse-magic.py:32- Finding
Unrestricted Local File Encoding and Upload to an External API
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is mostly coherent for HappyHorse video generation, but it needs Review because it can upload arbitrary local files to Alibaba DashScope without clearly documenting or limiting that behavior.
Review before installing. Only use this skill if you are comfortable sending prompts, media URLs, and any selected local media files to Alibaba DashScope. Ensure the agent passes only intended image/video files, not paths to private documents, .env files, keys, or credentials.
scripts/happyhorse-magic.py:32Unrestricted Local File Encoding and Upload to an External API
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f" Duration : {args.duration}s")
print(f" Watermark : {args.watermark}")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f" Duration : {args.duration}s")
print(f" Watermark : {args.watermark}")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f" Duration : {args.duration}s")
print(f" Watermark : {args.watermark}")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f" Duration : {args.duration}s")
print(f" Watermark : {args.watermark}")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f"[text2video-get] Checking task: {args.task_id}")
resp = requests.get(url, headers=headers, timeout=60)
result = resp.json()
if "code" in result:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f"[text2video-get] Checking task: {args.task_id}")
resp = requests.get(url, headers=headers, timeout=60)
result = resp.json()
if "code" in result:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f"[text2video-get] Checking task: {args.task_id}")
resp = requests.get(url, headers=headers, timeout=60)
result = resp.json()
if "code" in result:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
print(f"[text2video-get] Checking task: {args.task_id}")
resp = requests.get(url, headers=headers, timeout=60)
result = resp.json()
if "code" in result:
The skill uses environment variables and network access to call an external model service, but it does not declare an explicit tool scope such as permissions or allowed-tools. This weakens reviewability and containment because an agent may invoke capabilities broader than users or platform policy expect, especially when handling externally supplied URLs and API credentials.
The documentation instructs users to submit image and video URLs to a third-party video-generation service but does not warn that user-provided media, prompts, and possibly derived outputs will be sent off-platform for processing. This creates a real privacy and data-handling risk, particularly if users provide sensitive, copyrighted, biometric, or otherwise confidential media.
The documentation instructs users to send prompts and externally hosted reference-image URLs to a third-party video-generation API but does not warn that this transmits potentially sensitive content off-platform. In a media skill that encourages uploading character/object reference images, omission of a privacy/data-sharing warning can lead users to unknowingly expose personal images, copyrighted assets, or confidential prompts to an external service.
This markdown file documents a network API that transmits user-provided video and image URLs to a remote service and requires an API key in the Authorization header. The description does not include any warning about sending potentially sensitive media to a third-party service or protecting credentials, which fits the markdown-specific missing user warnings criterion.
The helper accepts local file paths, base64-encodes their full contents, and sends them to a third-party cloud API, while the CLI does not present any explicit privacy, consent, or data-handling warning. In a skill context, users may provide sensitive images or videos assuming local processing, making unintended external transfer a realistic confidentiality risk.
This submission transmits user prompts and potentially sensitive generated-content instructions to an external service. In this tool's context that behavior is functional and expected, but it is still security-relevant because users may not realize their inputs are leaving the local environment and could include confidential information.
print(f" Duration : {args.duration}s")
print(f" Watermark : {args.watermark}")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
This request can upload full local image content after converting it to a data URI, meaning sensitive local media is transmitted to a remote API. In a media-editing skill this is expected functionality, but it increases the danger because users may supply private photos without a clear notice that the content is being exfiltrated from the local machine to a third party.
print(f" Resolution : {args.resolution}")
print(f" Duration : {args.duration}s")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
This call uploads one or more reference images, which may contain biometric, personal, or proprietary visual data, to an external cloud service. Because the skill supports multi-image character/reference fusion, the contextual likelihood of users providing sensitive identity-bearing images makes the confidentiality concern more significant.
print(f" Ratio : {args.ratio}")
print(f" Duration : {args.duration}s")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
This operation can transmit an entire local video plus optional reference images to a remote API, creating substantial risk of exposing sensitive audiovisual content. In the editing-skill context, users are especially likely to upload personal or confidential recordings, so silent external transfer is more dangerous than ordinary text-only API use.
print(f" Resolution : {args.resolution}")
print(f" Audio : {args.audio_setting}")
resp = requests.post(url, headers=headers, json=payload, timeout=60)
result = resp.json()
if "code" in result:
This markdown file documents remote HTTP API usage and shows that prompts and media URLs are sent to an external endpoint, but it does not include any user-facing warning about data leaving the local environment. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors that could affect user data or privacy.
The only prompt examples shown in both request and response use Chinese text, which can imply a fixed language expectation. Because the document does not state that the API is Chinese-only, region-specific, or that users may choose their own language, this may violate the language/locale policy criterion.
The example request hard-codes a Chinese-language prompt, which may imply a language preference in the skill documentation without stating that other languages are acceptable. Because the file does not justify a locale-specific constraint or offer explicit user language choice, this can be interpreted as a mild language/locale policy issue.
The documentation uses a Chinese-only example instruction in the request body and repeats it in the sample response, without offering an alternative language example or stating that the API is region- or language-specific. This can be read as implicitly forcing a specific language in the skill documentation without user opt-in.