Back to skill

Security audit

Video Intent Studio

Security checks for vulnerabilities and agentic risk

Overview

The skill’s video workflow is mostly coherent, but it needs review because the generator can send an Ark API key and prompt to a configurable endpoint without validating the destination.

Install only if you are comfortable using a Volcengine Ark API key and sending final prompts to Ark. Avoid setting ARK_VIDEO_TASKS_URL unless you fully trust and have verified the endpoint, keep the API key out of shared logs or files, and prefer a limited-scope key with quotas or rotation.

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

Error
Location
scripts/generate_ark_video.py:24
Finding
Ark API Credential and User Prompt Disclosure Through an Unrestricted Task Endpoint## Vulnerability Details **File Location**: `scripts/generate_ark_video.py`, lines 24-30, 84-94, and 151-157 **Vulnerability Type**: Arbitrary authenticated endpoint / sensitive information disclosure **Risk Level**: High ### Vulnerable Code ```python parser.add_argument("--api-key", help="Ark API key, otherwise read from environment") parser.add_argument("--model", default=os.environ.get("ARK_VIDEO_MODEL", DEFAULT_MODEL), help="Model name") parser.add_argument( "--tasks-url", default=os.environ.get("ARK_VIDEO_TASKS_URL", DEFAULT_TASKS_URL), help="Task endpoint URL", ) ``` ```python def request_json(method: str, url: str, api_key: str, data: dict | None = None) -> dict: req = urllib.request.Request(url, method=method) req.add_header("Content-Type", "application/json") req.add_header("Authorization", f"Bearer {api_key}") payload = None if data is not None: payload = json.dumps(data).encode("utf-8") try: with urllib.request.urlopen(req, data=payload) as response: body = response.read().decode("utf-8") ``` ```python task_payload = request_json("POST", args.tasks_url, api_key, payload) task_id = extract_task_id(task_payload) if not task_id: raise RuntimeError(f"Task created without id: {json.dumps(task_payload, ensure_ascii=False)}") start_time = time.time() last_status_payload = None while True: last_status_payload = request_json("GET", f"{args.tasks_url}/{task_id}", api_key) ``` ### Technical Analysis The task endpoint can be supplied through either the `--tasks-url` command-line argument or the `ARK_VIDEO_TASKS_URL` environment variable. The supplied value is not restricted to the declared Volcengine Ark service, is not required to use HTTPS, and is not checked against an approved hostname. The `request_json()` function unconditionally adds the resolved Ark API key as a bearer token to every request. The ini ...[truncated 2700 chars]
Remediation
## Remediation Suggestions 1. **Remove unnecessary endpoint configurability.** If this Skill exclusively supports Volcengine Ark, use the fixed official endpoint and remove `--tasks-url` and `ARK_VIDEO_TASKS_URL`. 2. **Apply an exact destination allowlist.** If endpoint overrides are operationally required: - Require the `https` scheme. - Permit only documented Volcengine Ark hostnames, such as `ark.cn-beijing.volces.com`. - Reject embedded credentials, fragments, unexpected ports, IP literals, and hostname suffix tricks. - Normalize the hostname before comparison and use exact matching rather than substring or suffix matching. 3. **Secure redirect handling.** Disable automatic redirects for authenticated requests or validate every redirect target before forwarding the `Authorization` header. Never forward credentials across origins. 4. **Separate endpoint trust from user input.** Do not allow ordinary prompt content or agent-controlled parameters to select the authenticated service endpoint. Endpoint configuration should come only from trusted administrator-controlled configuration. 5. **Fail closed.** Abort generation when endpoint validation fails. Do not silently fall back to or contact an unapproved destination. 6. **Use least-privilege credentials.** Use a key scoped only to the required video-generation API, with quotas, expiration, monitoring, and rotation enabled. 7. **Warn on exceptional configuration.** If support for non-default official regional endpoints is necessary, display the validated destination and require explicit confirmation before transmitting credentials and prompt data. 8. **Add security tests.** Cover HTTP URLs, lookalike domains, attacker-controlled subdomains, embedded user information, alternate ports, IP addresses, and cross-origin redirects. Verify that no bearer token is sent when validation fails.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented behavior presents a benign staged guidance workflow, but the detected implementation reportedly omits those controls and instead performs undeclared credential lookup from the Windows registry and downloads files to the local filesystem. That mismatch is dangerous because it defeats user and reviewer expectations, hides sensitive operations, and may expose local secrets or write untrusted remote content to disk under the guise of a simple prompt-refinement skill.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill invokes helper scripts that require environment access for API credentials and network access for remote video generation, but the manifest declares no corresponding tool scope or permissions. This creates a transparency and containment gap: the agent may access secrets and external services without explicit declaration or user review, increasing the risk of unintended credential use or data exfiltration.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The guide's user-facing response examples and confirmation flow are written as mandatory Chinese interaction patterns, with no indication that users may choose another language. This is a natural-language policy concern because it imposes a locale/language without opt-in or documented justification.

External Transmission

Medium
Category
Data Exfiltration
Content
payload = json.dumps(data).encode("utf-8")

    try:
        with urllib.request.urlopen(req, data=payload) as response:
            body = response.read().decode("utf-8")
    except urllib.error.HTTPError as exc:
        detail = exc.read().decode("utf-8", errors="replace")
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code embeds multiple Chinese-only video type names, summaries, and keyword triggers as core skill behavior, which steers the skill toward a specific language/locale without offering any user choice. The file does not document that the skill is intended only for a Chinese-language or region-specific audience, so this appears to violate the language/locale policy.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This markdown file tells users to set `ARK_API_KEY` for generation, which involves handling a credential, but it does not include any warning about keeping the key secret or avoiding accidental sharing in logs, screenshots, or checked-in files. For markdown files, missing warnings about privacy- or security-relevant behavior can be flagged when the description omits them.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The file hard-codes only two language categories for ranking hints: 'Chinese hints' and 'English hints'. This can amount to a language/locale policy issue because it constrains handling to specific languages without documenting user choice, opt-in, or a justified region-specific limitation.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
def merge_params(video_type: dict, args: argparse.Namespace) -> dict:
    params = deepcopy(video_type["defaults"])
    for key in ("duration", "ratio", "motion", "style", "brightness", "subtitle", "dream_filter"):
        value = getattr(args, key, None)
        if value is not None:
            params[key] = value
    return params
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Static analysis

No suspicious patterns detected.