Back to skill

Security audit

Cn Video Gen

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real AI-video helper, but it needs Review because it can upload local files to a public image host using embedded credentials without enough scoping or warnings.

Review before installing. Use only non-sensitive image files, assume uploaded images may become publicly reachable or retained by a third party, replace or remove the embedded ImgURL credential, and avoid invoking the uploader on arbitrary paths until file validation, size limits, workspace restrictions, and explicit confirmation are added.

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

Warning
Location
scripts/upload_image.py:13
Finding
Hard-Coded Third-Party Upload Credential<![CDATA[ ## Vulnerability Details **File Location**: `scripts/upload_image.py:13-14` **Vulnerability Type**: Hard-coded reusable API credential **Risk Level**: Medium ### Vulnerable Code ```python IMGURL_UID = os.environ.get("IMGURL_UID", "rrbhyq") IMGURL_TOKEN = os.environ.get("IMGURL_TOKEN", "sk-[REDACTED EXPOSED TOKEN]") ``` The token value has been redacted from this report but is stored in plaintext in the original source code. ### Technical Analysis The ImgURL UID and API token have hard-coded fallback values. When the corresponding environment variables are absent, every installation of the Skill silently uses the same embedded account credential. Supporting environment variables does not mitigate the issue because the committed fallback remains recoverable by anyone who can download or inspect the Skill. A reusable authentication secret must not be distributed in source code or package artifacts. ### Attack Path 1. An attacker obtains a copy of the publicly distributed or locally installed Skill. 2. The attacker opens `scripts/upload_image.py` and extracts the embedded UID and token. 3. The attacker sends requests directly to the ImgURL upload API using those credentials. 4. Requests are attributed to the shared ImgURL account rather than to the attacker. 5. The attacker can consume the account's upload allowance and exercise any other permissions granted to the exposed token. No local code execution or elevated operating-system privileges are required to exploit this issue. ### Impact Assessment The exposed credential can permit unauthorized use of the associated third-party account. Potential consequences include: - Upload quota or storage consumption. - Service abuse attributed to the credential owner. - Unexpected billing, if the account is connected to paid services. - Loss of accountability because all Skill users share one identity. - Possible exposure or manipulation of account resources if the token grants capabilities beyond uplo ...[truncated 174 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the exposed ImgURL token immediately. 2. Remove all hard-coded credential fallback values: ```python IMGURL_UID = os.environ.get("IMGURL_UID") IMGURL_TOKEN = os.environ.get("IMGURL_TOKEN") if not IMGURL_UID or not IMGURL_TOKEN: raise RuntimeError( "IMGURL_UID and IMGURL_TOKEN must be configured explicitly" ) ``` 3. Store credentials in a supported secret manager or protected runtime environment variables. 4. Issue separate credentials for each deployment or user instead of sharing one account identity. 5. Restrict the replacement token to the minimum API permissions and quota required for image upload. 6. Add automated secret scanning to source-control and release pipelines. 7. Review repository history and previously published packages because deleting the current value does not remove it from older artifacts. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/upload_image.py:17
Finding
Arbitrary Local Files Can Be Uploaded to a Third-Party Public Host<![CDATA[ ## Vulnerability Details **File Location**: `scripts/upload_image.py:17-37, 62-70` **Vulnerability Type**: Unrestricted local-file read and external upload **Risk Level**: High ### Vulnerable Code ```python def upload_image(image_path: str) -> str: """上传图片到 ImgURL,返回公网直链 URL""" boundary = "----FormBoundary7MA4YWxkTrZu0gW" with open(image_path, "rb") as f: file_data = f.read() filename = os.path.basename(image_path) body = ( f"--{boundary}\r\n" f'Content-Disposition: form-data; name="uid"\r\n\r\n' f"{IMGURL_UID}\r\n" f"--{boundary}\r\n" f'Content-Disposition: form-data; name="token"\r\n\r\n' f"{IMGURL_TOKEN}\r\n" f"--{boundary}\r\n" f'Content-Disposition: form-data; name="file"; filename="{filename}"\r\n' f"Content-Type: image/png\r\n\r\n" ).encode() + file_data + f"\r\n--{boundary}--\r\n".encode() req = urllib.request.Request( IMGURL_API, data=body, headers={"Content-Type": f"multipart/form-data; boundary={boundary}"}, method="POST" ) ``` ```python if __name__ == "__main__": if len(sys.argv) < 2: print("用法: python3 upload_image.py <图片路径>", file=sys.stderr) sys.exit(1) image_path = sys.argv[1] if not os.path.exists(image_path): print(f"❌ 文件不存在: {image_path}", file=sys.stderr) sys.exit(1) print(f"📤 上传图片: {image_path}") url = upload_image(image_path) print(f"✅ 上传成功: {url}") print(url) ``` ### Technical Analysis The script accepts an arbitrary caller-supplied filesystem path and only checks whether that path exists. It does not verify that the selected object is a regular image file. The complete contents are read and sent to `https://www.imgurl.org/api/v2/upload`, while the multipart request unconditionally labels the data as `image/png`. The following controls are absent: - Image decoding and format verification. - MIME-type and extension ...[truncated 2670 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict uploads to explicitly approved workspace directories: - Resolve the path with `Path.resolve()`. - Verify that it is beneath an approved root. - Reject paths outside that root. 2. Require a regular file and reject directories, devices, pipes, and symlinks. 3. Enforce a conservative maximum file size before reading or uploading. 4. Decode the input with a trusted image library and allow only required formats such as PNG, JPEG, or WebP. Do not rely solely on file extensions or caller-provided MIME types. 5. Derive the MIME type from the successfully decoded image rather than always declaring `image/png`. 6. Re-encode validated images before upload to ensure that non-image trailing data is not transmitted. 7. Request explicit user confirmation that identifies: - The exact local file. - The external destination. - Whether the resulting link may be public. 8. Prefer a private, access-controlled upload mechanism or direct provider upload instead of a public image host. 9. Stream the validated file rather than loading the entire file and multipart body into memory. 10. Add audit logging for the approved path, byte count, destination host, and upload result without recording credentials. 11. Consider an API that accepts a constrained image object instead of exposing a general filesystem-path argument to agent-controlled workflows. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

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

Critical
Category
Data Flow
Content
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
    
    try:
        with urllib.request.urlopen(req) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
)

    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read().decode())
            if result.get("code") == 200:
                url = result["data"]["url"]
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The skill claims to be a video-generation helper, but its instructions include uploading local images to a third-party image host and using credentials for API access without clearly presenting those data-transfer risks in the declared behavior. In a skill handling user media, undeclared outbound transmission is especially sensitive because local files may contain private or proprietary content.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill claims to be a video-generation helper, but its instructions include uploading local images to a third-party image host and using credentials for API access without clearly presenting those data-transfer risks in the declared behavior. In a skill handling user media, undeclared outbound transmission is especially sensitive because local files may contain private or proprietary content.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documents use of environment variables, external APIs, image upload, and file transfer, but does not declare any tool scope or permission boundaries. This makes the skill harder to audit and increases the chance an agent can access network or secrets more broadly than users expect.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs users to upload local images to a public image host to obtain a URL, but gives no warning that the image may become publicly accessible or retained by a third party. This can expose sensitive personal, internal, or copyrighted images beyond the user's intent.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill advises downloading generated videos locally and sending them to Feishu without warning about local storage, retention, or third-party transmission. This can leak sensitive generated content or metadata and may leave residual files on disk after transfer.

External Transmission

Medium
Category
Data Exfiltration
Content
**文档:** https://klingai.kuaishou.com/api/docs

**端点:** `https://api.klingai.com/v1/videos/text2video`

**认证:** 需要 JWT Token(用 Access Key + Secret Key 生成)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The module docstring presents the script name, supported features, and usage instructions only in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly justified, which is not provided here.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
Argument help text, validation errors, and status output are all emitted in Chinese, with no option to choose another language. This enforces a single language for operation and troubleshooting, which matches the language/locale policy violation described in SQP-3.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
This skill is presented as a video-generation capability, but the file implements image upload to a public hosting provider. That scope expansion matters because it introduces data exfiltration/public-publication behavior that a user invoking a video tool may not reasonably expect, increasing the chance that local images are exposed externally without informed consent.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The script contains built-in fallback API credentials, including what appears to be a live token, and uses them automatically if environment variables are absent. Hardcoded secrets can be abused by anyone with access to the code, may incur unauthorized usage/costs, and indicate poor secret-management hygiene in a component that transmits data to a third-party service.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script uploads a user-specified local file to a public image-hosting service and returns a public URL, but there is no explicit privacy warning or consent gate. In the context of an AI media skill, users may provide personal, proprietary, or sensitive images, so silent public disclosure materially increases the risk of accidental data exposure.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The description says the skill triggers when the user asks to generate a video, turn an image into a dynamic video, or generate clips from storyboard descriptions, but it does not define clear boundaries or exclusions. Phrases like '要求生成视频' are broad enough to match many ordinary creative requests, which could cause unintended invocation without more specific trigger constraints.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The script accesses upload credentials without any user-facing disclosure, which reduces transparency around third-party service use and account context. While less severe than the hardcoded-secret issue, hidden credential use can mislead operators about which external account receives uploaded content and can complicate accountability and incident response.

Static analysis

No suspicious patterns detected.