Back to skill

Security audit

qwencloud-video-generation

Security checks for vulnerabilities and agentic risk

Overview

The skill mainly performs QwenCloud video generation, but it has review-worthy risks around API-key forwarding to configurable endpoints and unpinned skill/update installation prompts.

Review this skill before installing. Use it only in trusted workspaces, avoid workspace-provided .env files unless you understand every QWEN_* setting, do not set QWEN_BASE_URL except for a trusted HTTPS gateway, and treat any local media paths as uploads to QwenCloud or configured OSS storage. Decline or carefully review the optional update-check and package install prompts unless they are pinned to a trusted version.

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/qwencloud_lib.py:271
Finding

Workspace-Controlled API Endpoint Can Receive QwenCloud Credentials

Content
View full analysis
None: """Load ``.env`` files with proper priority: current dir > repo root.""" load_dotenv(Path.cwd() / ".env") origin = Path(script_file).resolve() if script_file else None if origin: repo = find_repo_root(origin) if repo: load_dotenv(repo / ".env") ``` ```python def native_base_url(self) -> str: custom = os.getenv("QWEN_BASE_URL") region = os.getenv("QWEN_REGION", "ap-southeast-1").lower() if region == "none": if not custom: raise RuntimeError( "QWEN_BASE_URL must be set when QWEN_REGION=none." ) return custom.rstrip("/") if custom: parsed = urllib.parse.urlparse(custom.rstrip("/")) return f"{parsed.scheme}://{parsed.netloc}/api/v1" return self._NATIVE_BASE.get(region, self._NATIVE_BASE["ap-southeast-1"]) ``` ```python def make_headers( self, api_key: str, payload: Any = None, ) -> dict[str, str]: hdrs: dict[str, str] = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", } if payload and self.has_managed_url(payload): hdrs["X-DashScope-OssResourceResolve"] = "enable" source_cfg = build_source_config() if source_cfg: hdrs["X-DashScope-Source-Config"] = source_cfg return hdrs ``` ```python load_env(script_file) provider = get_provider() fallback_env = provider.get_api_key_env_name() key = os.environ.get("QWEN_API_KEY", "").strip() if not key: key = os.environ.get(fallback_env, "").strip() ``` `` ...[truncated 2577 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:289
Finding

Mutable Third-Party Dependencies and Skill Updates Are Installed Without Integrity Pinning

Content
View full analysis
/gossamer.py --dismiss` ``` ```python _SKILLS_REPO = "QwenCloud/qwencloud-ai" INSTALL_CMD = ( f"npx skills add {_SKILLS_REPO} " "--skill qwencloud-update-check -y" ) ``` The media-processing guide provides a version pin for MoviePy, but no integrity hash: ```bash python3 -m venv .venv source .venv/bin/activate pip install "moviepy==2.2.1" ``` ### Technical Analysis The Skill recommends installing Python packages and a remotely sourced QwenCloud Skill without immutable integrity controls: - `pip install moviepy` resolves the latest package version. - `pip install alibabacloud-oss-v2` resolves the latest package version. - The `npx skills add` command references a mutable repository rather than a reviewed commit or release digest. - The version-pinned MoviePy example does not use package hashes. Package installation and remotely sourced Skill installation can execute or later load code supplied by external registries and repositories. Because versions, commits, and hashes are not consistently pinned, the effective code can differ from the code r ...[truncated 1640 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (35)

Tainted flow: 'req' from os.getenv (line 687, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 349)May include surrounding context.

python
headers={"Content-Type": ct},
        )
        try:
            with urllib.request.urlopen(req, timeout=120) as resp:
                if resp.status != 200:
                    raise RuntimeError(f"OSS upload HTTP {resp.status}")
        except urllib.error.HTTPError as exc:

Tainted flow: 'req' from os.getenv (line 687, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 458)May include surrounding context.

python
"Content-Type": "application/json",
            },
        )
        with urllib.request.urlopen(req, timeout=30) as resp:
            body = json.loads(resp.read().decode("utf-8"))
        data = body.get("data")
        if not data:

Tainted flow: 'req' from os.getenv (line 687, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 689)May include surrounding context.

python
for attempt in range(retries + 1):
        req = urllib.request.Request(url, data=data, headers=hdrs, method=method)
        try:
            with urllib.request.urlopen(req, timeout=timeout) as resp:
                return json.loads(resp.read().decode("utf-8"))
        except urllib.error.HTTPError as exc:
            body = ""

Tainted flow: 'req' from os.getenv (line 687, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 745)May include surrounding context.

python
data = json.dumps(payload).encode("utf-8")
    req = urllib.request.Request(url, data=data, headers=hdrs, method="POST")
    try:
        resp = urllib.request.urlopen(req, timeout=timeout)
    except urllib.error.HTTPError as exc:
        body = ""
        try:

Tainted flow: 'req' from os.getenv (line 687, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

download_file accepts an arbitrary URL and fetches it directly, then writes the response to disk with no validation of scheme, host, size, or destination safety constraints. If higher-level skill inputs can influence this URL, the function can be used for SSRF-style access to internal network resources or to download unexpected content to the local filesystem.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 841)May include surrounding context.

python
"""Download a file from *url* to *dest*, creating parent dirs as needed."""
    dest.parent.mkdir(parents=True, exist_ok=True)
    req = urllib.request.Request(url, headers={"User-Agent": "qwencloud-ai/1.0"})
    with urllib.request.urlopen(req, timeout=timeout) as resp:
        dest.write_bytes(resp.read())
    return dest

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose is video generation, but the skill also contains mandatory update-check, install prompting, and skill-management behavior. This mismatch is dangerous because it normalizes unrelated system-modifying actions under a benign media workflow, increasing the chance of unnecessary installs, state changes, or cross-skill execution without clear user intent.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This file implements cross-skill update-check and installation prompting behavior that is unrelated to the declared purpose of a video-generation skill. That mismatch is dangerous because it expands the skill's authority and nudges users toward installing additional code, increasing supply-chain and trust-boundary risk beyond expected video functionality.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 87)May include surrounding context.

python
script_file : str or Path, optional
        ``__file__`` of the calling script, used to locate the repo root.
    """
    load_dotenv(Path.cwd() / ".env")
    origin = Path(script_file).resolve() if script_file else None
    if origin:
        repo = find_repo_root(origin)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 92)May include surrounding context.

python
script_file : str or Path, optional
        ``__file__`` of the calling script, used to locate the repo root.
    """
    load_dotenv(Path.cwd() / ".env")
    origin = Path(script_file).resolve() if script_file else None
    if origin:
        repo = find_repo_root(origin)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 406)May include surrounding context.

python
ak_id = os.getenv("OSS_ACCESS_KEY_ID", "")
            ak_secret = os.getenv("OSS_ACCESS_KEY_SECRET", "")
            credentials_provider = (
                oss.credentials.EnvironmentVariableCredentialsProvider()
            )

        cfg = oss.config.load_default()

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/qwencloud_lib.py (reported line 590)May include surrounding context.

python
Local paths are auto-uploaded to DashScope temp storage (48h TTL).

environment variables:
  DASHSCOPE_API_KEY  (required) API key — also loaded from .env
  QWEN_API_KEY       (alternative)
  QWEN_REGION        ap-southeast-1 (default)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/video.py (reported line 138)May include surrounding context.

python
Local paths are auto-uploaded to DashScope temp storage (48h TTL).

environment variables:
  DASHSCOPE_API_KEY  (required) API key — also loaded from .env
  QWEN_API_KEY       (alternative)
  QWEN_REGION        ap-southeast-1 (default)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs use of shell, network, filesystem, and environment access but declares no explicit tool scope or permission boundaries. That increases the chance an agent will execute high-impact actions without policy gating, especially because the document includes commands that read env state, write files, and install software.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are broad enough to match many ordinary requests about creating or editing videos, which can cause over-invocation of a powerful skill. In context, that matters because the skill can access files, environment variables, network resources, and shell commands, so unnecessary triggering increases exposure to side effects.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SKILL.md (reported line 41)May include surrounding context.

md
**NEVER output any API key or credential in plaintext.** Always use variable references (`$DASHSCOPE_API_KEY` in shell, `os.environ["DASHSCOPE_API_KEY"]` in Python). Any check or detection of credentials must be **non-plaintext**: report only status (e.g. "set" / "not set", "valid" / "invalid"), never the value. Never display contents of `.env` or config files that may contain secrets.

**When the API key is not configured, NEVER ask the user to provide it directly.** Instead, help create a `.env` file with a placeholder (`DASHSCOPE_API_KEY=sk-your-key-here`) and instruct the user to replace it with their actual key from the [QwenCloud Console](https://home.qwencloud.com/api-keys). Only write the actual key value if the user explicitly requests it.

## Key Compatibility

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation mandates installing and managing another skill via npm/npx as part of the workflow, even though that is not necessary for core video generation. This broadens the attack surface by introducing package installation and local state mutation into a content-generation task, which could be abused or triggered unexpectedly.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

The skill directs the agent to run npx skills add ... without pinning an exact package or version, creating a supply-chain risk. If the upstream package changes or is compromised, the agent could install and execute unintended code during a post-execution flow unrelated to the user's video task.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file instructs agents to derive trigger keywords by scraping broad natural-language descriptions from sibling skills, specifically the text between 'TRIGGER when:' and 'DO NOT TRIGGER'. Because this extraction is unconstrained and based on free text, a malicious or poorly written sibling skill could inject overly broad, misleading, or adversarial trigger phrases that cause incorrect skill activation or prompt-routing behavior.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api-guide.md (reported line 35)May include surrounding context.

bash
# Step 1: Submit
curl -sS 'https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis' \
  -H 'X-DashScope-Async: enable' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -H 'Content-Type: application/json' \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The examples demonstrate sending local file paths and remote media URLs to a cloud video-generation workflow without any warning that referenced media may be uploaded to a third-party service and processed remotely. In this skill context, users are likely to test with personal images, videos, or audio, so omission of privacy and data-handling guidance can lead to unintentional disclosure of sensitive content.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/execution-guide.md (reported line 14)May include surrounding context.

md
3. **SSL errors** (`CERTIFICATE_VERIFY_FAILED`): On macOS, run `/Applications/Python\ 3.x/Install\ Certificates.command`. On Linux/Windows, set `SSL_CERT_FILE` to point to your CA bundle.
4. **Proxy**: Set `HTTPS_PROXY=http://proxy:port` before running the script.

After fixing, retry the script (Path 1). If the environment is unfixable, fall through to **Path 2 (curl)** below — curl is available on most systems without Python.

## Path 2 · Direct API Call (curl)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The manifest scopes this skill to generating or editing videos using Wan/QwenCloud video APIs, but this guide additionally instructs the agent to perform media merging operations such as concat, trim, and audio overlay via ffmpeg or moviepy. Those are broader local media-processing capabilities that are not clearly justified by the stated cloud video-generation purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code manages discovery, prompting, and update workflow for another skill (qwencloud-update-check), which is unjustified in the context of a video-generation tool. This creates an unnecessary capability for influencing the local skill environment and can be abused to socially engineer users into installing or updating remote components.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

The code emits an installation command using npx skills add without pinning a specific package or skill version, encouraging downstream execution of whatever version is current at install time. That creates a supply-chain risk: a compromised or malicious future release could be installed when users follow the prompt.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

The generated update command reconstructs npx skills add for installed skills without version pinning, which can upgrade users to unreviewed latest content. In a skill ecosystem, that broadens supply-chain exposure because following the suggested command may fetch changed remote code for multiple skills.

Content

No source excerpt is available for this finding.