Back to skill

Security audit

apifox-image-gen

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill does what it claims, but it needs review because it bundles an API key and can download and write API-controlled content without strong limits.

Install only if you are comfortable sending image prompts to jyapi.AI-WX.CN and accepting a bundled shared API key. Avoid sensitive prompts, avoid using --output outside a disposable directory, and prefer a revised version that loads the API key from user-controlled secrets, restricts download hosts, validates image content and size, and prevents overwriting arbitrary files.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
image_gen.py:14
Finding
Hard-Coded API Credential Exposed in Source Code## Vulnerability Details **File Location**: `image_gen.py`, lines 14-24 **Vulnerability Type**: Hard-coded secret and insecure credential management **Risk Level**: High ### Vulnerable Code ```python API_KEY = "sk-hJP0yrKv2H7A4mjy39D8C3D5Dd17492494A65f4bCbE9859e" BASE_URL = "https://jyapi.AI-WX.CN" def generate_image(prompt, model="gpt-image-1.5", size="1024x1024", n=1, image=None): url = f"{BASE_URL}/v1/images/generations" headers = { "Authorization": API_KEY, "Content-Type": "application/json" } ``` ### Technical Analysis A live-looking API credential is embedded directly in the distributed Python source and transmitted in the authorization header on every generation request. Anyone who can read the Skill package can extract and reuse the credential outside the intended application. Authentication is necessary for the declared image-generation functionality, but embedding a shared credential in source code is not necessary and violates least-privilege credential-management practices. The key cannot be isolated per user, rotated without changing the package, or protected using filesystem or secret-manager controls. ### Attack Path 1. An attacker obtains or reads the Skill package. 2. The attacker extracts the `API_KEY` value from `image_gen.py`. 3. The attacker sends independent requests to the configured API using the extracted authorization value. 4. Requests are attributed to the exposed credential until the service revokes or rotates it. ### Impact Assessment Exploitation may permit unauthorized use of the API account associated with the credential. The scope includes consumption of API quota, potential billing impact, service abuse, rate-limit exhaustion, and loss of reliable request attribution. The exposed key does not directly grant local system privileges, but it grants whatever remote API permissions are assigned to that credential.
Remediation
## Remediation Suggestions 1. Immediately revoke and rotate the exposed credential. 2. Remove all credentials from source code and repository history. 3. Read the credential from a protected environment variable or secret manager: ```python API_KEY = os.environ.get("APIFOX_API_KEY") if not API_KEY: raise RuntimeError("APIFOX_API_KEY is not configured") ``` 4. Use a dedicated credential with only the permissions and quota required for image generation. 5. Prefer per-user or short-lived credentials instead of a shared package-level secret. 6. Add automated secret scanning to development and release workflows. 7. Confirm the API's required authorization scheme and use the documented header format.

T09 · Insecure Skill Coding Practices

Error
Location
image_gen.py:47
Finding
Unvalidated Server-Controlled Image Download URL## Vulnerability Details **File Location**: `image_gen.py`, lines 47-54 and 91-99 **Vulnerability Type**: Unrestricted URL retrieval and server-side request forgery risk **Risk Level**: High ### Vulnerable Code ```python def download_image(url, save_path=None): if not save_path: save_path = f"/tmp/image_{uuid.uuid4().hex[:8]}.png" try: urllib.request.urlretrieve(url, save_path) return save_path except Exception as e: return None ``` ```python for i, img in enumerate(images): img_url = img.get("url") if img_url: if args.output: save_path = args.output else: save_path = f"/tmp/generated_image_{i+1}_{uuid.uuid4().hex[:8]}.png" downloaded = download_image(img_url, save_path) ``` ### Technical Analysis The remote image-generation service controls the `url` field returned in each response. The program passes that value directly to `urllib.request.urlretrieve` without validating the URL scheme, destination host, resolved IP address, redirects, content type, response size, or file signature. If the external service, its account, or an upstream component is compromised, it can cause the Agent to request arbitrary network locations accessible from the Agent's environment. This creates a server-side request forgery primitive. Depending on supported URL handlers and runtime configuration, unexpected non-HTTPS resources may also be accepted. The implementation also trusts that the downloaded response is an image. A malicious endpoint can return arbitrary or excessively large content, resulting in disk consumption or attacker-controlled data being written to the selected destination. ### Attack Path 1. An attacker gains influence over the configured API response or compromises the remote service. 2. The service returns an image object whose `url` points to an internal, loopback, link-local, ...[truncated 985 chars]
Remediation
## Remediation Suggestions 1. Permit only `https` download URLs. 2. Maintain an explicit allowlist of trusted image-delivery hostnames. 3. Resolve the hostname before connecting and reject loopback, private, link-local, reserved, multicast, and unspecified IP ranges. 4. Disable automatic redirects or validate the scheme, hostname, and resolved address after every redirect. 5. Replace `urlretrieve` with a bounded streaming download that enforces: - A strict connection and read timeout. - A maximum response size. - A maximum redirect count. - An expected image content type. 6. Verify downloaded file signatures using a trusted image parser before treating the content as an image. 7. Execute downloads in a network-restricted environment that can reach only the API and approved content hosts. 8. Delete partial files when validation or download fails.

T09 · Insecure Skill Coding Practices

Error
Location
image_gen.py:91
Finding
Caller-Controlled Output Path Allows Arbitrary File Overwrite## Vulnerability Details **File Location**: `image_gen.py`, lines 69-70 and 91-99 **Vulnerability Type**: Unrestricted file write and unsafe path handling **Risk Level**: High ### Vulnerable Code ```python parser.add_argument('--output', '-o', help='Output file path') ``` ```python for i, img in enumerate(images): img_url = img.get("url") if img_url: if args.output: save_path = args.output else: save_path = f"/tmp/generated_image_{i+1}_{uuid.uuid4().hex[:8]}.png" downloaded = download_image(img_url, save_path) ``` The selected path reaches the following write operation: ```python urllib.request.urlretrieve(url, save_path) ``` ### Technical Analysis The `--output` argument accepts an unrestricted filesystem path. The path is used as the destination of `urlretrieve` without canonicalization, directory confinement, an existing-file check, or symlink protection. A caller who can influence command-line arguments can therefore select any file writable by the Agent's operating-system account. Existing files may be replaced. A pre-created symbolic link can also redirect the write to another writable target. This exceeds the minimum privileges required by the declared functionality, which states that generated images are saved under `/tmp/`. Image generation requires writing an output image, but it does not require unrestricted write access to arbitrary filesystem locations. ### Attack Path 1. An attacker or untrusted caller influences the arguments passed to the Skill through its permitted execution interface. 2. The attacker supplies a sensitive writable location using `--output`. 3. The image API returns a URL, potentially containing attacker-controlled non-image content if combined with the unvalidated download issue. 4. `urlretrieve` opens the selected destination and writes the downloaded response. 5. The target file is created ...[truncated 803 chars]
Remediation
## Remediation Suggestions 1. Restrict all generated files to a dedicated output directory owned by the Skill. 2. Resolve the canonical destination and verify that it remains beneath the approved directory. 3. Accept a filename rather than an arbitrary absolute path, and reject path separators and traversal components. 4. Reject symbolic links and use operating-system flags that prevent following symlinks. 5. Create new files atomically with restrictive permissions and fail if the destination already exists. 6. Generate unique destinations for every image when `n` is greater than one. 7. Validate the downloaded content as an image before moving it to the final destination. 8. Run the Skill under a dedicated, low-privilege account with no write access to configuration, executable, or persistence-sensitive locations.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill declares simple image generation, but the finding indicates the underlying behavior also includes a hardcoded API key and downloading remote content to the local filesystem. That creates hidden trust and data-handling risks not disclosed in the skill description, including credential exposure and unsafe persistence of untrusted remote data.

Lp1

High
Category
MCP Least Privilege
Confidence
98% confidence
Finding
The script performs outbound network access to a third-party API and to arbitrary image URLs, but this capability is not declared in the skill permissions. Undeclared network behavior is dangerous because it can exfiltrate prompts or other sensitive data and bypass the user's expected trust boundary.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill documentation does not warn users that their prompts are sent to a third-party image-generation API. Users may unknowingly transmit sensitive, proprietary, or personal information to an external service, creating privacy, compliance, and data-governance risk.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
User-supplied prompts are transmitted to an external API without an explicit warning or consent flow. This is risky because prompts may contain sensitive business, personal, or proprietary data that the user does not expect to leave the local environment.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill does more than generate images via an API: it also fetches a remote URL from the API response and writes the content to local disk. This expands the attack surface because a compromised or malicious API could return unexpected URLs, causing unreviewed remote content retrieval and local file creation.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
Allowing the caller to provide an arbitrary output path permits the tool to write downloaded content anywhere the process has filesystem access. In agent contexts, this can overwrite sensitive files, place files in unexpected locations, or be chained with other behaviors for persistence or tampering.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The user-facing description and usage instructions are presented in Chinese throughout the file, with no indication that this language choice is optional or region-specific. Under the language/locale policy, forcing a specific language without user opt-in can be a natural-language policy issue.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
Natural-language strings and documentation in this file are entirely in Chinese, including the module description and CLI help text. There is no indication that the user can choose a language or that the locale restriction is intentional and justified for a region-specific tool.

Static analysis

No suspicious patterns detected.