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<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.py:112-121, 145-147` **Vulnerability Type**: Arbitrary credential-bearing network request **Risk Level**: High ### Vulnerable Code ```python def _post_json(url: str, api_key: str, payload: dict[str, Any]) -> 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
<![CDATA[ ## Remediation Suggestions 1. Remove arbitrary `base_url` support unless it is operationally required. 2. Allowlist the exact supported HTTPS endpoints: - `https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation` - `https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation` 3. Parse URLs with `urllib.parse.urlsplit` and require: - The `https` scheme. - An exact approved hostname. - The expected API path. - No embedded username or password. - No unexpected port. 4. Disable redirects or validate every redirect target and reject cross-origin redirects. 5. If custom endpoints must remain supported, do not automatically attach the DashScope key. Require a separately supplied credential explicitly intended for that endpoint. 6. Avoid including credentials, authorization headers, or complete request URLs in logs and exception output. 7. Add tests proving that HTTP, loopback, private-network, malformed, and non-DashScope endpoints are rejected before any network request occurs. ]]>

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<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.py:175-178, 204` **Vulnerability Type**: SSRF and unrestricted remote response download **Risk Level**: Medium ### Vulnerable Code ```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()) ``` ```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
<![CDATA[ ## Remediation Suggestions 1. Accept image URLs only from documented, trusted Alibaba Cloud image-delivery domains. If the provider uses variable domains, maintain an explicit and reviewed suffix allowlist with correct hostname-boundary checks. 2. Require HTTPS and reject URLs containing embedded credentials, unexpected ports, or unsupported schemes. 3. Resolve the destination and reject loopback, private, link-local, multicast, reserved, and cloud-metadata addresses for both IPv4 and IPv6. 4. Disable redirects or validate each redirect destination using the same scheme, hostname, and address controls. 5. Configure connection and read timeouts. 6. Stream the response in bounded chunks instead of calling `response.read()` without a limit. 7. Enforce a conservative maximum image size and abort the download when the limit is exceeded. 8. Validate the response `Content-Type` and verify the downloaded file's image signature before retaining it. 9. Download to a safely created temporary file, validate it, and then atomically move it to the requested destination. 10. Add tests covering loopback URLs, private addresses, IPv6 address forms, redirects to internal hosts, non-image responses, oversized bodies, and stalled connections. ]]>
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
Content
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())
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.

Credential Access

High
Category
Privilege Escalation
Content
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")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
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")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
_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)
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

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.

External Transmission

Medium
Category
Data Exfiltration
Content
## 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 '{
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.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

Missing User Warnings

Low
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.

Intent-Code Divergence

Low
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.

Static analysis

No suspicious patterns detected.