Back to skill

Security audit

Media.io Vidu Video Generator

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do what it claims, but its API-key handling has a credible redirect-related exposure risk users should review before installing.

Install only if you are comfortable sending prompts, image URLs, generation settings, and a Media.io API key to Media.io. Use a scoped or low-credit API key if possible, avoid confidential or regulated content, and consider fixing the router to disable redirects before using it with a valuable key.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/skill_router.py:51
Finding
API Key Disclosure Through Cross-Origin HTTP Redirects<![CDATA[ ## Vulnerability Details **File Location**: `scripts/skill_router.py`, lines 51–67 **Vulnerability Type**: Credential disclosure through unsafe redirect handling **Risk Level**: Medium ### Vulnerable Code ```python # Restrict outbound requests to the expected Media.io API host. parsed = urlparse(url) if parsed.scheme != 'https' or parsed.netloc.lower() != 'openapi.media.io': return {'error': f"Blocked endpoint host: {parsed.netloc}"} headers = { 'X-API-KEY': resolved_api_key, 'Content-Type': 'application/json' } # Replace path parameters in endpoint URLs. if '{' in url: for k, v in params.items(): url = url.replace(f'{{{k}}}', str(v)) # Keep non-path parameters in the JSON body. body = {k: v for k, v in params.items() if f'{{{k}}}' not in api['endpoint']} try: resp = requests.request(method, url, headers=headers, json={'data': body} if body else {}, timeout=30) ``` ### Technical Analysis The implementation verifies that the initial request URL uses HTTPS and has the exact hostname `openapi.media.io`. However, `requests.request()` follows HTTP redirects by default, while the code does not validate the destination of each redirect. The API credential is carried in the custom `X-API-KEY` header. Custom authentication headers are not guaranteed to be removed automatically when a redirect crosses origins. Therefore, if the validated Media.io endpoint returns a redirect to another hostname, the client may send the API key to that destination. The initial hostname check does not protect subsequent redirect hops. Exploitation requires the legitimate endpoint, or infrastructure controlling its response, to issue a cross-origin redirect. No evidence was found that ordinary request parameters currently let an untrusted caller directly select such a redirect destination, so the issue is conditional rather than an immediate arbitrary-host request vulnerability. ### Attack Path 1. A victim invokes one of the configured Media.io ...[truncated 1069 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Disable automatic redirects for authenticated API requests: ```python resp = requests.request( method, url, headers=headers, json={'data': body} if body else {}, timeout=30, allow_redirects=False, ) ``` If redirects are required, handle them explicitly and apply all of the following controls: 1. Validate every redirect destination before sending another request. 2. Require the `https` scheme and the exact hostname `openapi.media.io`. 3. Reject user-information components, unexpected ports, and malformed hostnames. 4. Enforce a small redirect limit to prevent redirect loops. 5. Never forward `X-API-KEY` when the scheme, hostname, or effective port changes. 6. Prefer rejecting redirects entirely for fixed API endpoints because all configured destinations are already known. 7. Add automated tests covering same-origin redirects, cross-origin redirects, scheme downgrades, malformed destinations, and redirect loops. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (7)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill clearly integrates with Media.io OpenAPI, but the documentation does not warn users that prompts and uploaded images will be transmitted to an external third-party service for processing. This can lead to unintentional disclosure of sensitive data, especially if users assume processing is local or only within the agent environment.

External Transmission

Medium
Category
Data Exfiltration
Content
"description": "API to query user credits balance.",
    "api_header": "{\"list\": [{\"name\": \"X-API-KEY\", \"value\": \"API key to authorize requests\"}, {\"name\": \"Content-Type\", \"value\": \"application/json\"}], \"title\": \"Authorizations\", \"describe\": \"Add the following authorization information in the request header\"}",
    "api_body": "{\"title\": \"Request Body\", \"category\": [{\"list\": [], \"title\": \"Query Credits\", \"describe\": \"Request body to query user credits balance\"}]}",
    "api_request_demo": "{\"title\": \"Example Request\", \"request\": [{\"title\": \"Query User Credits\", \"language\": \"cURL\", \"code_example\": \"curl --request POST \\n  --url https://openapi.media.io/user/credits \\n  --header 'Content-Type: application/json' \\n  --header 'X-API-KEY: <api-key>' \\n  --data '{}'\"}]}",
    "api_response": "{\"list\": [{\"name\": \"code\", \"type\": \"integer\", \"describe\": \"Response status code, 0 indicates success\"}, {\"name\": \"msg\", \"type\": \"string\", \"describe\": \"Response message, empty string on success\"}, {\"name\": \"data\", \"type\": \"object\", \"describe\": \"Response data object\"}, {\"name\": \"credits\", \"type\": \"integer\", \"describe\": \"User credits balance, located within the data object\"}], \"title\": \"Response\", \"describe\": \"After the request is successfully processed, the server will return the following response\"}",
    "api_code_demo": "{\"list\": [{\"code\": \"0\", \"describe\": \"Success\"}, {\"code\": \"40001\", \"describe\": \"Invalid API key\"}, {\"code\": \"40002\", \"describe\": \"API key expired\"}], \"title\": \"Status Code\"}",
    "content": null,
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The Vidu Q2 entry documents submitting an image URL and prompt to `https://openapi.media.io/generation/vidu/i2v-vidu-q2`, but there is no user-facing disclosure that potentially sensitive user content is transmitted off-system for processing. Because this file is a JSON documentation/manifest file, SQP-2 applies to missing warnings about privacy-impacting behavior.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The Vidu Q3 image-to-video entry describes uploading user-controlled content and parameters, including image URL, prompt, and audio-generation options, to a remote generation endpoint, but it does not disclose the privacy implications of that transfer. This is a documentation omission affecting user awareness of external processing.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The text-to-video entry documents sending prompts and generation preferences to a remote API endpoint but does not warn users that their text inputs will leave the local environment and be processed by an external provider. That is a missing privacy disclosure under SQP-2 for this manifest/documentation file.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This code accesses a sensitive credential via API_KEY and sends it to a remote service in the X-API-KEY header. Although the behavior is functionally required, the file provides no user-facing prompt, print/log notice, or explicit warning comment/docstring that credentials will be used and transmitted.

Missing User Warnings

Low
Confidence
84% confidence
Finding
This JSON manifest documents outbound HTTP requests that require sending an `X-API-KEY` header to `openapi.media.io`, but it provides no warning about handling credentials or the fact that authentication data is transmitted to a third-party endpoint. For markdown and manifest-style documentation, SQP-2 applies when descriptions omit warnings about behaviors affecting privacy or system integrity.

Static analysis

No suspicious patterns detected.