Human Avatar

Security checks across malware telemetry and agentic risk

Overview

This skill coherently provides Alibaba Cloud avatar, image, video, and speech generation, but users should treat it as a cloud media-processing tool that can upload sensitive media and use cloud credentials.

Install only if you are comfortable sending selected images, videos, audio, text, and generated outputs to Alibaba Cloud services. Use least-privilege Alibaba credentials, a dedicated OSS bucket or prefix, private buckets with short signed-URL lifetimes, lifecycle cleanup for temporary objects, and avoid setting endpoint override variables unless you fully trust the destination.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Tainted flow: 'BASE_URL' from os.getenv (line 38, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
Returns output dict with check_pass, bodystyle.
    """
    print(f"\n[step1] aa-detect …")
    r = requests.post(
        f"{BASE_URL}/api/v1/services/aigc/image2video/aa-detect",
        headers=_headers(async_mode=False),
        json={"model": "animate-anyone-detect-gen2", "input": {"image_url": image_url}},
Confidence
89% confidence
Finding
r = requests.post( f"{BASE_URL}/api/v1/services/aigc/image2video/aa-detect", headers=_headers(async_mode=False), json={"model": "animate-anyone-detect-gen2", "input": {"ima

Tainted flow: 'BASE_URL' from os.getenv (line 38, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
Returns template_id str.
    """
    print(f"\n[step2] aa-template-generation …")
    r = requests.post(
        f"{BASE_URL}/api/v1/services/aigc/image2video/aa-template-generation/",
        headers=_headers(async_mode=True),
        json={"model": "animate-anyone-template-gen2", "input": {"video_url": video_url}},
Confidence
89% confidence
Finding
r = requests.post( f"{BASE_URL}/api/v1/services/aigc/image2video/aa-template-generation/", headers=_headers(async_mode=True), json={"model": "animate-anyone-template-gen2",

Tainted flow: 'BASE_URL' from os.getenv (line 38, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"input": {"image_url": image_url, "template_id": template_id},
        "parameters": {"use_ref_img_bg": use_ref_img_bg, "video_ratio": video_ratio},
    }
    r = requests.post(
        f"{BASE_URL}/api/v1/services/aigc/image2video/video-synthesis/",
        headers=_headers(async_mode=True),
        json=payload,
Confidence
89% confidence
Finding
r = requests.post( f"{BASE_URL}/api/v1/services/aigc/image2video/video-synthesis/", headers=_headers(async_mode=True), json=payload, timeout=60, )

Tainted flow: 'url' from os.getenv (line 149, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
url = f"{BASE_URL}/api/v1/tasks/{task_id}"
    start = time.time()
    while time.time() - start < max_wait:
        r = requests.get(url, headers=_headers(), timeout=60)
        r.raise_for_status()
        data = r.json()
        out = data.get("output", {})
Confidence
87% confidence
Finding
r = requests.get(url, headers=_headers(), timeout=60)

Tainted flow: 'endpoint' from os.getenv (line 121, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
payload = {"model": model, "input": inp, "parameters": params}

    print(f"\n[i2v] submit  model={model}  resolution={resolution}  duration={duration}s")
    r = requests.post(endpoint, headers=_headers(async_mode=True), json=payload, timeout=60)
    r.raise_for_status()
    data = r.json()
    task_id = (data.get("output") or {}).get("task_id")
Confidence
90% confidence
Finding
r = requests.post(endpoint, headers=_headers(async_mode=True), json=payload, timeout=60)

Tainted flow: 'url' from os.environ.get (line 79, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
url = f"{BASE_URL}/api/v1/tasks/{task_id}"
    start = time.time()
    while time.time() - start < max_wait:
        r = requests.get(url, headers=_headers(async_mode=False), timeout=30)
        r.raise_for_status()
        data = r.json()
        out = data.get("output", {})
Confidence
89% confidence
Finding
r = requests.get(url, headers=_headers(async_mode=False), timeout=30)

Tainted flow: 'BASE_URL' from os.getenv (line 41, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
Raises ValueError if check fails.
    """
    print(f"\n[step1] liveportrait-detect …")
    r = requests.post(
        f"{BASE_URL}/api/v1/services/aigc/image2video/face-detect",
        headers=_headers(async_mode=False),
        json={"model": "liveportrait-detect", "input": {"image_url": image_url}},
Confidence
86% confidence
Finding
r = requests.post( f"{BASE_URL}/api/v1/services/aigc/image2video/face-detect", headers=_headers(async_mode=False), json={"model": "liveportrait-detect", "input": {"image_ur

Tainted flow: 'BASE_URL' from os.getenv (line 41, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"head_move_strength": head_move_strength,
        },
    }
    r = requests.post(
        f"{BASE_URL}/api/v1/services/aigc/image2video/video-synthesis/",
        headers=_headers(async_mode=True),
        json=payload,
Confidence
86% confidence
Finding
r = requests.post( f"{BASE_URL}/api/v1/services/aigc/image2video/video-synthesis/", headers=_headers(async_mode=True), json=payload, timeout=60, )

Tainted flow: 'url' from os.environ.get (line 102, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
start = time.time()
    while time.time() - start < max_wait:
        try:
            r = requests.get(url, headers=_headers(), timeout=30)
            r.raise_for_status()
            data = r.json()
            out = data.get("output", {})
Confidence
84% confidence
Finding
r = requests.get(url, headers=_headers(), timeout=30)

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill declares required binaries and environment variables and clearly describes capabilities that involve network access, file reads/writes, and shelling out to ffmpeg, but it does not declare corresponding permissions. This creates a transparency and governance gap: the platform or reviewer may underestimate what the skill can access or execute, increasing the risk of unintended data exposure or over-privileged execution.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The trigger text is broad enough to activate on many common content-creation requests, including generic requests for images, videos, or speech synthesis. Over-broad triggering can cause the wrong skill to run in unrelated contexts, leading to unexpected network calls, use of sensitive API-backed services, or processing of user-provided media without sufficiently specific user intent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation states that local files are automatically converted and uploaded to OSS, but it does not explicitly warn users that their images and videos will be transmitted to external cloud storage and processing services. In a skill handling human portraits, voice, and video generation, this omission can cause users to unknowingly expose sensitive biometric or personal media, creating privacy, retention, and compliance risks.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document instructs users to upload local files to OSS and expose them via public or signed URLs so a third-party service can fetch them, but it does not clearly warn that this transfers user content outside the local environment and may expose sensitive images, audio, or biometric data. In the context of a human-avatar/video generation skill, the uploaded assets are likely to include face images and voice recordings, which materially increases privacy risk.

Missing User Warnings

Low
Confidence
87% confidence
Finding
Using a default 3-day signed URL validity period grants external access substantially longer than the documented processing window of minutes, increasing the chance of unintended disclosure if the URL is logged, shared, or intercepted. While not an exploit by itself, it weakens least-privilege and data-minimization practices for sensitive media.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script can automatically copy public templates into the user's LingMou account as a side effect when no local templates exist, and this also occurs through the normal execution path via choose_template(..., auto_copy_public=True). That is a real safety issue because it performs a persistent write action on remote account state without an explicit confirmation step, which can surprise users, create unwanted resources, and potentially incur quota, governance, or compliance issues.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
When local --image or --audio files are provided, the script automatically uploads them to Alibaba OSS and then shares signed URLs with external DashScope services. In a skill that processes user media, this creates a real privacy and data-handling risk because sensitive files leave the local environment without any explicit consent prompt, minimization, or retention controls in the code.

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal