Back to skill

Security audit

MiVisionForgeSVOR

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent cloud video-removal tool, but it needs Review because a remote service can control result-download URLs without local validation or size/time limits.

Review before installing if you will run it on a network with internal services or with sensitive media. The skill uploads videos, prompts, masks, and an API key-authenticated request flow to the documented XiaomiTools service, then downloads results from URLs returned by that service. Use only non-sensitive test videos at first, prefer an isolated environment, and avoid shared machines for SVOR_API_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/video_remove.py:75
Finding

Unvalidated Result URL Enables Server-Side Request Forgery and Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/video_remove.py:75-78; remotely supplied values reach this function at lines 145 and 313
Vulnerability Type: Unvalidated outbound request, SSRF, and unbounded response handling
Risk Level: Medium

Vulnerable Code

python
def download_result(url, output_path):
    resp = requests.get(url)
    with open(output_path, "wb") as f:
        f.write(resp.content)

The function is invoked using result URLs supplied by the remote API:

python
download_result(seg_data["video_path"], mask_raw)
python
download_result(erase_data["video_path"], output)

Technical Analysis

The video_path field is controlled by the remote processing service and is passed directly to requests.get() without validating its scheme, hostname, resolved IP address, destination port, or redirect chain.

Because requests.get() follows redirects by default, validation would also need to cover every redirect target. A compromised, malicious, or incorrectly configured processing service could return a URL targeting loopback, link-local, private-network, or otherwise internal services reachable from the machine running the Skill.

The download also lacks:

  • Connection and read timeouts
  • HTTP status validation through raise_for_status()
  • Streaming response handling
  • A maximum response-size limit
  • Content-type or media-format validation

resp.content buffers the entire response in memory before writing it to disk. An excessively large or non-terminating response could therefore consume substantial memory, disk space, and execution time.

Attack Path

  1. A user runs the Skill with a local video.
  2. The script uploads the video to the configured remote processing API.
  3. The processing API, or an attacker controlling its response path, returns an attacker-selected value in video_path.
  4. The script passes that value directly to `download ...[truncated 1265 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require result URLs to use HTTPS.
  2. Maintain an explicit allowlist of trusted object-storage or result-download hostnames.
  3. Resolve the hostname before connecting and reject loopback, private, link-local, multicast, reserved, and unspecified IP ranges for both IPv4 and IPv6.
  4. Disable redirects with allow_redirects=False, or validate every redirect destination before following it.
  5. Configure strict connection and read timeouts.
  6. Call raise_for_status() before processing the response body.
  7. Download with stream=True and enforce a maximum byte count based on the expected video limits.
  8. Validate the response content type and verify the downloaded file as an expected video or mask before further processing.
  9. Remove incomplete output files if validation or downloading fails.
  10. Prefer an API design that returns an opaque result identifier and downloads results only through a fixed, trusted endpoint.

Example hardened pattern:

python
import ipaddress
import socket
from urllib.parse import urlparse

ALLOWED_DOWNLOAD_HOSTS = {"trusted-result-host.example"}

def validate_download_url(url):
    parsed = urlparse(url)
    if parsed.scheme != "https" or parsed.hostname not in ALLOWED_DOWNLOAD_HOSTS:
        raise ValueError("Untrusted result URL")

    for result in socket.getaddrinfo(parsed.hostname, parsed.port or 443):
        address = ipaddress.ip_address(result[4][0])
        if not address.is_global:
            raise ValueError("Non-public result address")

def download_result(url, output_path, max_bytes=50 * 1024 * 1024):
    validate_download_url(url)
    total = 0

    try:
        with requests.get(
            url,
            stream=True,
            timeout=(5, 30),
            allow_redirects=False,
        ) as resp:
            resp.raise_for_status()
            with open(output_path, "wb") as output:
                for chunk in r
...[truncated 437 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Tainted flow: 'HEADERS' from os.environ.get (line 39, credential/environment) → requests.post (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/video_remove.py (reported line 49)May include surrounding context.

python
def submit_segmentation(video_path, **kwargs):
    with open(video_path, "rb") as f:
        resp = requests.post(
            f"{BASE_URL}/customize/xiaomi-ev/video_obj_removal/customize/v1/videos/sam3_prompt_seg",
            headers=HEADERS,
            files={"input_video": f},

Tainted flow: 'HEADERS' from os.environ.get (line 39, credential/environment) → requests.get (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/video_remove.py (reported line 61)May include surrounding context.

python
def poll_task(endpoint, task_id, max_wait=300):
    for i in range(max_wait // 3):
        time.sleep(3)
        resp = requests.get(f"{BASE_URL}{endpoint}/status/{task_id}", headers=HEADERS)
        data = resp.json()
        status = data.get("status")
        print(f"  [{i*3}s] Status: {status}")

Tainted flow: 'HEADERS' from os.environ.get (line 39, credential/environment) → requests.post (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/video_remove.py (reported line 297)May include surrounding context.

python
# ===== Step 5: 消除 =====
    print(f"\n=== Step 5: Object removal ===")
    with open(input_for_seg, "rb") as vf, open(mask_merged, "rb") as mf:
        resp = requests.post(
            f"{BASE_URL}/customize/xiaomi-ev/video_obj_removal/customize/v1/videos/mieraser",
            headers=HEADERS,
            files={"input_video": vf, "input_mask": mf}

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill performs outbound network communication to a remote service without corresponding declared network permissions. In a permissioned skill platform, hidden network capability is dangerous because it allows local files and metadata to leave the environment without users or reviewers being properly informed.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill performs outbound network communication to a remote service without corresponding declared network permissions. In a permissioned skill platform, hidden network capability is dangerous because it allows local files and metadata to leave the environment without users or reviewers being properly informed.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest describes a video object removal skill, which clearly justifies video processing and even remote inference calls if that is how the feature is implemented. However, directly reading a credential from the process environment introduces secret-handling behavior that is not stated in the skill purpose and is broader than simple media processing.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/video_remove.py (reported line 44)May include surrounding context.

python
def compress_video(input_path, output_path, scale=512):
    cmd = ["ffmpeg", "-i", input_path, "-vf", f"scale={scale}:-2", "-crf", "32", "-y", output_path]
    subprocess.run(cmd, check=True, capture_output=True)


def submit_segmentation(video_path, **kwargs):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/video_remove.py (reported line 84)May include surrounding context.

python
def compress_video(input_path, output_path, scale=512):
    cmd = ["ffmpeg", "-i", input_path, "-vf", f"scale={scale}:-2", "-crf", "32", "-y", output_path]
    subprocess.run(cmd, check=True, capture_output=True)


def submit_segmentation(video_path, **kwargs):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/video_remove.py (reported line 99)May include surrounding context.

python
def compress_video(input_path, output_path, scale=512):
    cmd = ["ffmpeg", "-i", input_path, "-vf", f"scale={scale}:-2", "-crf", "32", "-y", output_path]
    subprocess.run(cmd, check=True, capture_output=True)


def submit_segmentation(video_path, **kwargs):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script uploads local video files and user-provided prompts/annotations to a remote API without an upfront, explicit warning at runtime or in the stated behavior. This is dangerous because videos may contain sensitive personal, commercial, or location data, and users could reasonably assume a local editing workflow from the tool description and ffmpeg-based processing steps.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill description and operational instructions are written entirely in Chinese, including usage guidance, warnings, and parameter explanations. This creates a locale/language constraint without any stated opt-in or alternative language support, which matches the policy concern for forced language selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module docstring, help text, and runtime error/output messages are written in Chinese only, 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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script writes downloaded results, temporary copies, compressed videos, masks, and merged outputs into the temp directory and may overwrite outputs via ffmpeg's -y flag. Although these writes are part of the tool's function, there is no explicit disclosure in the CLI description or module docstring that the tool creates and overwrites files under the working video directory.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.