Back to skill

Security audit

Alibaba Cloud AI Image Zimage Turbo

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent image generator, but its helper can send the API key to a caller-chosen endpoint and download unchecked remote content, so it needs review before use.

Review before installing. Use a dedicated, low-privilege DashScope API key, do not pass untrusted request JSON, avoid base_url or DASHSCOPE_BASE_URL unless it is one of the official HTTPS DashScope endpoints, and do not include secrets or sensitive personal data in image prompts. Treat any previous run with an untrusted endpoint as possible API-key exposure and rotate the 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_image.py:145
Finding

DashScope API Key Disclosure Through an Unrestricted Endpoint Override

Content
View full analysis
dict[str, Any]: data = json.dumps(payload, ensure_ascii=False).encode("utf-8") req = urllib.request.Request( url, data=data, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", }, method="POST", ) with urllib.request.urlopen(req) as response: body = response.read().decode("utf-8") return json.loads(body) ``` ```python base_url = req.get("base_url") or os.getenv("DASHSCOPE_BASE_URL") or DEFAULT_BASE_URL payload = _build_payload(req) resp = _post_json(base_url, api_key, payload) ``` ### Technical Analysis The request-controlled `base_url` is passed directly to `_post_json` without validating its scheme, hostname, port, path, or destination. `_post_json` attaches the user's DashScope API key as a bearer credential to every request. Although regional endpoint selection is necessary for the declared image-generation functionality, sending a DashScope credential to an arbitrary caller-selected origin is not necessary. The documented legitimate endpoints are limited to the Beijing and Singapore DashScope hosts. The implementation also permits a cleartext `http://` URL, which could expose the bearer credential and prompt to network observers. Redirect behavior is not constrained by an explicit same-origin policy, adding further uncertainty around where sensitive request data may be sent. ### Attack Path 1. The victim has a valid `DASHSCOPE_API_KEY` in the environment, a loaded `.env` file, or `~/.alibabacloud/credentials`. 2. An attacker persuades the victim or an invoking agent to process a request containing an attacker-controlled endpoint, for example: ...[truncated 978 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:175
Finding

Unvalidated Remote Image URL Enables Server-Side Request Forgery and Unbounded Downloads

Content
View full analysis
None: output_path.parent.mkdir(parents=True, exist_ok=True) with urllib.request.urlopen(image_url) as response: output_path.write_bytes(response.read()) ``` ```python result = call_generate(req) download_image(result["image_url"], Path(args.output)) ``` The URL originates from the remote API response: ```python image_url = _extract_image_url(resp) return { "image_url": image_url, "width": (resp.get("usage") or {}).get("width"), "height": (resp.get("usage") or {}).get("height"), "prompt": req.get("prompt"), "rewritten_prompt": _extract_text_field(content, "text"), "reasoning": _extract_text_field(content, "reasoning_content"), "request_id": resp.get("request_id"), } ``` ### Technical Analysis The script trusts the returned `image_url` and opens it without validating the scheme, destination address, hostname, port, redirect chain, response content type, or response size. The entire response is read into memory and then written to disk. A malicious or compromised API endpoint can therefore make the process connect to an arbitrary URL reachable from the victim's environment. This is particularly practical in combination with the unrestricted `base_url`, because an attacker-controlled API response can supply any desired image URL. The lack of size limits also permits memory or disk exhaustion. The lack of image validation means arbitrary response content can be written to the user-selected output path, although the script does not execute that content. ### Attack Path 1. An attacker controls the configured API endpoint or compromises an endpoint capable of returning a syntactically valid response. 2. The endpoint returns content containing ...[truncated 1518 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The script downloads a URL returned by the remote API and fetches it with urlopen without validating the scheme, host, or content type. If the upstream service is compromised, misconfigured, or if a user supplies a malicious base_url, this can trigger unintended outbound requests and write attacker-controlled content to disk, creating an SSRF-style trust boundary issue and unsafe file download path.

Content

Scanner excerpt · scripts/generate_image.py (reported line 176)May include surrounding context.

python
def download_image(image_url: str, output_path: Path) -> None:
    output_path.parent.mkdir(parents=True, exist_ok=True)
    with urllib.request.urlopen(image_url) as response:
        output_path.write_bytes(response.read())

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/generate_image.py (reported line 47)May include surrounding context.

python
def _load_env() -> None:
    _load_dotenv(Path.cwd() / ".env")
    repo_root = _find_repo_root(Path(__file__).resolve())
    if repo_root:
        _load_dotenv(repo_root / ".env")

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/generate_image.py (reported line 50)May include surrounding context.

python
def _load_env() -> None:
    _load_dotenv(Path.cwd() / ".env")
    repo_root = _find_repo_root(Path(__file__).resolve())
    if repo_root:
        _load_dotenv(repo_root / ".env")

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/generate_image.py (reported line 197)May include surrounding context.

python
_load_dashscope_api_key_from_credentials()
    if not os.environ.get("DASHSCOPE_API_KEY"):
        print(
            "Error: DASHSCOPE_API_KEY is not set. Configure it via env/.env or ~/.alibabacloud/credentials.",
            file=sys.stderr,
        )
        print("Example .env:\n  DASHSCOPE_API_KEY=your_key_here", file=sys.stderr)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents use of environment variables, filesystem output, and outbound network access, but it does not declare any explicit tool scope such as permissions or allowed-tools. That omission weakens policy enforcement and reviewability because an agent may be granted broader capabilities than users expect when invoking this skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill explicitly performs external transmission to a third-party API, including user-supplied prompt data and bearer-token authentication. In context this is expected functionality, but it remains a real security concern because any sensitive data included in prompts or logs may leave the local trust boundary and be exposed to external retention, billing, or compromise risks.

Content

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

Quick start (curl)

bash
curl -sS 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -d '{

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The request payload includes the user's prompt and is sent over HTTP to the DashScope API. Although network access is inherent to image generation, this script provides no explicit warning in its user-facing output or comments that user-supplied content will be transmitted to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code fetches an image from a remote URL and writes it to the user-specified output path, affecting local filesystem state. While the CLI has an --output argument, there is no confirmation prompt, logging/print statement, or in-code warning disclosing that remote data will be downloaded and saved locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The skill instructs use of an API key in authenticated requests to an external provider but does not clearly warn users that prompts and associated data will be transmitted off-platform. In an agent setting, missing disclosure can lead to unintended sharing of sensitive prompts or metadata with a third party.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The workflow says to confirm whether the operation is read-only or mutating and then run a minimal read-only query first. However, this skill's documented purpose is text-to-image generation via a generation API, and the surrounding documentation does not define any read-only query operation for this provider or model. That guidance contradicts the actual intent and likely behavior of the skill.

Content

No source excerpt is available for this finding.