Back to skill

Security audit

AI Video Asset Manager

Security checks for vulnerabilities and agentic risk

Overview

The skill’s video asset workflow is mostly coherent, but its downloader can fetch arbitrary URLs and write files outside the intended asset directory.

Review before installing. Use the project initializer only on intended project paths, and do not use the batch downloader with untrusted URLs or filenames until it enforces basename-only filenames, destination containment, no silent overwrites, HTTPS/host restrictions, private-network blocking, content-type validation, and download size limits.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/batch-download.py:10
Finding

Arbitrary File Write Through an Unsanitized Destination Filename

Content
View full analysis

Vulnerability Details

File Location: scripts/batch-download.py, lines 10–18 and 37–47
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: High

Vulnerable Code

python
def download_file(url: str, dest_path: Path, timeout: int = 30) -> bool:
    """下载单个文件"""
    try:
        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
        with urllib.request.urlopen(req, timeout=timeout) as response:
            data = response.read()
            dest_path.write_bytes(data)
python
    for item in sys.argv[2:]:
        if '|' in item:
            url, filename = item.split('|', 1)
        else:
            url = item
            filename = url.split('/')[-1].split('?')[0]
        
        if not filename:
            print(f"[SKIP] 无法从URL提取文件名: {url}")
            continue
        
        dest_path = dest_dir / filename
        ok = download_file(url.strip(), dest_path)

Technical Analysis

The filename following the URL|filename argument is controlled by the caller and is joined directly to dest_dir. The implementation does not reject absolute paths, parent-directory components, platform-specific path separators, or symbolic-link destinations.

For example, a filename such as ../../configuration.json can resolve outside the intended download directory. With pathlib, an absolute filename may also cause the intended destination directory to be discarded. The resulting path is passed to Path.write_bytes(), which overwrites an existing file without confirmation.

No post-resolution containment check is performed to verify that the final destination remains beneath dest_dir. The code also does not prevent writes through pre-existing symbolic links.

Attack Path

  1. An attacker or untrusted user convinces the Agent to process a crafted material-download request.
  2. The request supplies an arg ...[truncated 1178 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat supplied filenames strictly as basenames:
    • Reject absolute paths.
    • Reject .. path components.
    • Reject directory separators and platform-specific alternate separators.
    • Apply a conservative filename-character allowlist.
  2. Resolve and validate the destination before writing:
    • Resolve dest_dir to a canonical path.
    • Resolve the candidate destination.
    • Verify that the candidate is a child of the canonical destination directory.
  3. Reject symbolic-link destinations and inspect parent directories for unexpected links where the threat model includes local attackers.
  4. Avoid silently overwriting files. Use exclusive creation mode or require explicit authorization before replacement.
  5. Generate server-side filenames where possible and retain the original name only as metadata.
  6. Log rejected paths without exposing sensitive filesystem details.

A safe design should enforce containment immediately before opening the destination, rather than relying only on string-based filtering.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/batch-download.py:10
Finding

Unrestricted URL Fetching Enables SSRF and Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/batch-download.py, lines 10–18 and 37–47
Vulnerability Type: Server-side request forgery and unbounded response buffering
Risk Level: Medium

Vulnerable Code

python
def download_file(url: str, dest_path: Path, timeout: int = 30) -> bool:
    """下载单个文件"""
    try:
        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
        with urllib.request.urlopen(req, timeout=timeout) as response:
            data = response.read()
            dest_path.write_bytes(data)
python
    for item in sys.argv[2:]:
        if '|' in item:
            url, filename = item.split('|', 1)
        else:
            url = item
            filename = url.split('/')[-1].split('?')[0]
        
        if not filename:
            print(f"[SKIP] 无法从URL提取文件名: {url}")
            continue
        
        dest_path = dest_dir / filename
        ok = download_file(url.strip(), dest_path)

Technical Analysis

The script passes a caller-supplied URL directly to urllib.request.urlopen() without validating its scheme, hostname, port, or resolved IP address. It also does not enforce an approved-host policy or validate redirect destinations.

Consequently, the downloader may be induced to connect to loopback services, private network ranges, link-local endpoints, or cloud instance metadata services that are reachable from the Agent environment but not from the attacker.

The response is consumed with an unbounded response.read(). The timeout limits waiting time but does not impose a response-size limit. A sufficiently large response can therefore consume substantial memory before being written to disk, while repeated downloads can also consume available storage. No content-type validation ensures that the response is actually an expected image or video.

Attack Path

  1. An attacker or untrusted user ...[truncated 1551 chars]
Remediation
View remediation

Remediation Suggestions

  1. Allow only required schemes, preferably HTTPS.
  2. Use an explicit allowlist of approved media hosts where practical.
  3. Resolve the hostname before connecting and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges for both IPv4 and IPv6.
  4. Revalidate every redirect target and enforce a small redirect limit.
  5. Protect against DNS rebinding by ensuring the address actually used for the connection remains an approved resolved address.
  6. Restrict destination ports to expected web ports unless additional ports are explicitly required.
  7. Stream the response in fixed-size chunks rather than calling an unbounded read().
  8. Enforce a maximum download size using both Content-Length when available and a hard byte counter while streaming.
  9. Validate response content types and, where feasible, inspect file signatures before accepting files as images or videos.
  10. Apply per-request and aggregate download quotas, and remove partial files when validation or transfer fails.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose is asset management, but the workflow and commands also allow arbitrary URL downloading and writing retrieved content to local directories. That mismatch is risky because users and orchestrators may trust the skill as a documentation/management helper while it actually performs materially more powerful actions that can fetch untrusted content and persist it locally.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill describes capabilities that imply local file writes and network retrievals, but it does not declare any explicit tool scope or permission boundaries. This is dangerous because an agent may invoke filesystem and network actions without clear least-privilege constraints, increasing the chance of unintended downloads, overwrites, or abuse if triggered in the wrong context.

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 and include common phrases related to video creation and asset management, which can cause the skill to activate unintentionally. When a skill with file creation and network-download behavior is invoked too easily, it raises the likelihood of accidental execution of state-changing actions in unrelated conversations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs creation of local files and downloading material from user-provided URLs without any visible safety guidance, validation, or confirmation requirements. This is dangerous because it can enable retrieval of malicious or inappropriate content, path misuse, storage abuse, or accidental handling of sensitive internal URLs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

All natural-language instructions in the skill file are written in Chinese and the file does not indicate that language choice is optional or that the restriction is required for a region-specific purpose. Under the policy rule for language or locale constraints, this can amount to forcing a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The entire skill file is written in Chinese and provides no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific context. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script provides unrestricted remote download capability and writes attacker-controlled content to a local directory, which expands the skill beyond its stated asset-management purpose into a general file retrieval tool. In an agent context, this can be abused to fetch untrusted payloads, stage malware, pull sensitive intranet resources via SSRF-like behavior, or introduce unsafe files into downstream media workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code silently performs network access and writes the response body directly to disk without explicit disclosure, confirmation, or overwrite safeguards. This is dangerous because users or calling agents may not realize the skill can create or replace local files with untrusted remote content, enabling accidental clobbering of assets and introduction of malicious or malformed files into the environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's user-facing natural-language description and usage strings are entirely in Chinese, which imposes a specific language on users. There is no indication that the tool is region-specific or that users can opt into another language/locale.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comment at L114 says '复制模板文件', implying existing templates from the assets/templates directory will be used. However, the code never reads from TEMPLATE_DIR or copies any source files; it only creates new files containing a one-line placeholder at L120.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.