Back to skill

Security audit

Seedance 2.0 Al Video Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but its file-upload path can send any readable local file to an external API without strong scoping or confirmation.

Review before installing. Use it only in an isolated workspace, provide only intended media files, avoid secrets or private documents in reachable paths, and prefer explicit user confirmation before any --files upload. Pin dependencies if you operate it in a production or sensitive environment.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run_seedance.py:188
Finding
Unrestricted Local File Upload Can Expose Sensitive Host Data## Vulnerability Details **File Location**: `scripts/run_seedance.py:188-201`, with the resulting network transmission at `scripts/run_seedance.py:219-225` and `scripts/run_seedance.py:255-262` **Vulnerability Type**: Arbitrary local file disclosure through unrestricted multipart upload **Risk Level**: High ### Vulnerable Code ```python def open_files_for_upload(paths: List[str]) -> List[Tuple[str, Tuple[str, Any, str]]]: """Open local files and return list of (form_key, (filename, fileobj, content_type)) for multipart upload.""" result = [] for path in paths: path = path.strip() if not path: continue if not os.path.isfile(path): raise FileNotFoundError(f"File not found: {path}") f = open(path, "rb") name = os.path.basename(path) mime, _ = mimetypes.guess_type(path) mime = mime or "application/octet-stream" result.append(("files", (name, f, mime))) return result ``` The files selected by this function are passed directly to the remote service: ```python upload_paths = filter_files_by_url_overrides( file_paths=args.files or [], image_urls=image_urls or [], video_urls=video_urls or [], audio_urls=audio_urls or [], ) file_tuples = open_files_for_upload(upload_paths) if upload_paths else [] ``` ```python resp = requests.post( VID_URL, headers={ "Authorization": f"Bearer {api_key}", }, data=data, files=file_tuples, timeout=120, ) ``` ### Technical Analysis The `--files` argument accepts arbitrary filesystem paths. The implementation checks only whether each path refers to a regular file. It does not: - Restrict files to a dedicated upload or workspace directory. - Resolve and validate canonical paths against an approved root. - Reject symbolic links that resolve outside an approved directory. - Restrict uploads to supported image, video, or audio formats. - Validate file contents against their claime ...[truncated 1970 chars]
Remediation
## Remediation Suggestions 1. Create a dedicated media-upload directory, such as `workspace/assets`, and permit uploads only from that directory. 2. Resolve every supplied path with `Path.resolve(strict=True)` and verify that the canonical path remains under the approved root. 3. Reject symbolic links or open files using platform-supported no-follow protections to reduce symlink and time-of-check/time-of-use risks. 4. Allowlist supported media types and extensions. Reject `other` files rather than uploading them as `application/octet-stream`. 5. Inspect file signatures with a trusted media parser instead of relying solely on filename-based `mimetypes.guess_type()`. 6. Enforce per-file and aggregate upload-size limits before opening or transmitting data. 7. Require explicit user confirmation listing the canonical path, detected media type, size, and destination before upload. 8. Run the Skill under an operating-system identity with access only to the intended workspace and no unnecessary credential directories. 9. Log upload metadata without recording file contents or authorization tokens.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Dependencies Permit Unreviewed Future Package Versions## Vulnerability Details **File Location**: `requirements.txt:1-2` **Vulnerability Type**: Non-reproducible dependency resolution without integrity verification **Risk Level**: Medium ### Vulnerable Code ```text requests>=2.28.0 python-dotenv>=1.0.0 ``` The documented installation command resolves those mutable constraints directly: ```bash pip install -r requirements.txt ``` ### Technical Analysis Both dependencies use open-ended minimum-version constraints. A future installation can therefore resolve package versions that were not present or reviewed when the Skill was audited. No lock file, exact version pin, package hash, or integrity-enforcing installation option is provided. The package names correspond to established dependencies and no typosquatting or dependency-confusion package was identified. The issue is that the effective dependency code can change over time without any corresponding change to this repository. Python packages may execute code during installation or whenever imported. Consequently, compromise of an upstream release, a malicious publication, or an incompatible future version could affect the Skill environment. ### Attack Path 1. A future version of `requests`, `python-dotenv`, or one of their transitive dependencies is compromised, maliciously modified, or introduces a security regression. 2. A user follows the documented `pip install -r requirements.txt` procedure. 3. Because the constraints specify only minimum versions, the package resolver selects the newer, unreviewed release. 4. Package installation or subsequent import executes that release in the Skill environment. 5. Malicious or vulnerable dependency code gains the permissions of the user running the installation or Skill. This path depends on an upstream compromise or unsafe future release; the audited repository does not itself contain evidence that the named packages are currently malicious. ### Impact Assessment Dependency code executes with t ...[truncated 551 chars]
Remediation
## Remediation Suggestions 1. Pin every direct dependency to a reviewed exact version, for example with `package==version`. 2. Generate a lock file that includes all transitive dependencies for supported Python and platform versions. 3. Record cryptographic hashes and install with pip’s `--require-hashes` option. 4. Obtain packages only from an explicitly configured trusted index. 5. Review dependency updates through a controlled process that includes vulnerability scanning and tests. 6. Rebuild and refresh the lock file regularly rather than relying on unrestricted automatic upgrades. 7. Perform dependency installation and Skill execution in an isolated, least-privileged virtual environment or container.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (31)

Credential Access

High
Category
Privilege Escalation
Content
```bash
# Copy from example
cp .env.example .env
# Edit .env and set:
LOOVA_API_KEY=your_api_key_here
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# Copy from example
cp .env.example .env
# Edit .env and set:
LOOVA_API_KEY=your_api_key_here
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
Seedance 2.0 Video Generator – Loova Seedance 2.0 script.
Loads LOOVA_API_KEY from environment or .env file.
Usage: python scripts/run_seedance.py --prompt "prompt" [--model ...] [--duration 5] [--ratio "16:9"] [--files "path1.jpg,path2.jpg"] [--image-urls "https://...,..."] [--video-urls "..."] [--audio-urls "..."]
Sends request as multipart/form-data when uploading files; otherwise sends application/json.
"""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The quick-start explicitly instructs users to pass local file paths for upload to the Loova Seedance API, but it does not clearly warn that those files leave the local machine and are transmitted to a third-party service. In an agent/skill context, users may assume local processing, so this omission can cause accidental disclosure of sensitive images, videos, or audio.

External Transmission

Medium
Category
Data Exfiltration
Content
## Overview

- **Submit** – `POST https://api.loova.ai/api/v1/video/seedance-2` to create a video generation task
- **Poll** – `GET https://api.loova.ai/v1/tasks?task_id=...` until the task completes
- **Auth** – `Authorization: Bearer <API_KEY>`; get your API key after logging in at [loova.ai](https://loova.ai/)
Confidence
86% confidence
Finding
The README documents that prompts, uploaded local media, and an API key are sent to an external third-party service at api.loova.ai. In the context of an agent skill that may process user-provided files, this is a real data exfiltration boundary that users may not fully appreciate, even though it is also the intended functionality of the skill.

External Transmission

Medium
Category
Data Exfiltration
Content
## Overview

- **Submit** – `POST https://api.loova.ai/api/v1/video/seedance-2` to create a video generation task
- **Poll** – `GET https://api.loova.ai/v1/tasks?task_id=...` until the task completes
- **Auth** – `Authorization: Bearer <API_KEY>`; get your API key after logging in at [loova.ai](https://loova.ai/)

## Upload to ClawHub
Confidence
80% confidence
Finding
The polling endpoint confirms continued interaction with the external Loova task API and implies task identifiers and result metadata are exchanged with a third party. This is not inherently malicious, but it is a real external transmission surface in an agent environment handling user content.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill declares environment and network capabilities in metadata but does not declare an explicit tool scope such as permissions or allowed-tools. This weakens platform governance because the agent may invoke networked behavior and access LOOVA_API_KEY without a clear least-privilege declaration or user-visible boundary.

External Transmission

Medium
Category
Data Exfiltration
Content
displayName: Seedance 2.0 AI Video Generator (Text to Video, Image to Video, Reference to Video)
description: Generates video via Loova Seedance 2.0 API (Seedance 2.0 video). Requires LOOVA_API_KEY from .env or environment (get API key at loova.ai). Use when the user asks for Loova, Seedance 2.0, image-to-video, or Seedance 2.0 video.

metadata: {"openclaw":{"homepage":"https://api.loova.ai/api","requires":{"bins":[],"env":["LOOVA_API_KEY"]},"primaryEnv":"LOOVA_API_KEY"}}
---

# Seedance 2.0 Video Generator
Confidence
94% confidence
Finding
The skill is explicitly designed to send user prompts and optional media to an external third-party service at api.loova.ai. Any uploaded images, video, audio, and prompt content may leave the local environment, which is a real data-exfiltration/privacy risk if users are not clearly informed or if sensitive content is submitted.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill says uploaded media should be saved locally in the workspace, but it does not clearly warn users that their chat-uploaded files will be written to disk before being sent onward. This can surprise users, increase retention of sensitive media, and create local exposure if the workspace is shared or later accessed by other tools.

External Transmission

Medium
Category
Data Exfiltration
Content
## API Flow

1. **Submit** – `POST https://api.loova.ai/api/v1/video/seedance-2` with `Authorization: Bearer <API_KEY>`; response contains `task_id`.
2. **Poll** – `GET https://api.loova.ai/api/v1/tasks?task_id=<task_id>` **once per minute** until status is succeeded or failed.
3. **Result** – Response includes the video result (e.g. URL). Script prints full JSON.
Confidence
95% confidence
Finding
This API flow documents a POST request carrying the API key and generation inputs to a third-party endpoint. Because the skill handles user-supplied content and uploads, the external transmission is genuine and can expose private media or prompts outside the platform boundary.

External Transmission

Medium
Category
Data Exfiltration
Content
## API Flow

1. **Submit** – `POST https://api.loova.ai/api/v1/video/seedance-2` with `Authorization: Bearer <API_KEY>`; response contains `task_id`.
2. **Poll** – `GET https://api.loova.ai/api/v1/tasks?task_id=<task_id>` **once per minute** until status is succeeded or failed.
3. **Result** – Response includes the video result (e.g. URL). Script prints full JSON.

## Parameters Summary
Confidence
90% confidence
Finding
The polling endpoint continues communicating task identifiers with the third-party service until completion. While lower sensitivity than the initial upload, it still confirms ongoing external communication and may expose metadata such as task IDs, timing, and result URLs.

Whitespace Padding

Medium
Category
Prompt Injection
Content
- application/json: `{ "model": string, "prompt": string, ... }` (all params at the top level)


| Field                 | Type          | Required | Description                                                                                       |
| --------------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------- |
| `model`               | string        | Yes      | `seedance_2_0` or `seedance_2_0_fast`                                                             |
| `prompt`              | string        | Yes      | Prompt; supports @ reference syntax                                                               |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# Load .env from current directory or project root
load_dotenv()

VID_URL = "https://api.loova.ai/api/v1/video/seedance-2"
VIDEO_ITEM_URL = "https://api.loova.ai/api/v1/tasks"
POLL_INTERVAL_SEC = 60  # Poll once per minute
MAX_POLL_COUNT = 180
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# Load .env from current directory or project root
load_dotenv()

VID_URL = "https://api.loova.ai/api/v1/video/seedance-2"
VIDEO_ITEM_URL = "https://api.loova.ai/api/v1/tasks"
POLL_INTERVAL_SEC = 60  # Poll once per minute
MAX_POLL_COUNT = 180
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# Load .env from current directory or project root
load_dotenv()

VID_URL = "https://api.loova.ai/api/v1/video/seedance-2"
VIDEO_ITEM_URL = "https://api.loova.ai/api/v1/tasks"
POLL_INTERVAL_SEC = 60  # Poll once per minute
MAX_POLL_COUNT = 180
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# Load .env from current directory or project root
load_dotenv()

VID_URL = "https://api.loova.ai/api/v1/video/seedance-2"
VIDEO_ITEM_URL = "https://api.loova.ai/api/v1/tasks"
POLL_INTERVAL_SEC = 60  # Poll once per minute
MAX_POLL_COUNT = 180
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
This script uploads arbitrary local media files provided via --files to a third-party API, but only signals that behavior in help text and docstrings. In an agent-skill context, that can lead to unintended disclosure of sensitive local images, video, or audio if the caller does not receive a clear runtime confirmation that local files are being exfiltrated off-host.

Static analysis

No suspicious patterns detected.