Back to skill

Security audit

AI Image Gen

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill does what it broadly claims, but it under-discloses sensitive API-key and prompt handling through configurable third-party endpoints and allows unrestricted local file output paths.

Review the provider endpoint before installing or running this skill. Use a narrowly scoped, revocable API key, avoid sensitive prompts, and do not let untrusted requests choose the output path. Treat the editing and image-to-image claims as unsupported unless the package is updated with clear implementation and scoping.

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:13
Finding

API Credential and Prompt Disclosure Through an Unrestricted Endpoint

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_image.py:13-47
Vulnerability Type: Unrestricted outbound endpoint and sensitive-data disclosure
Risk Level: High

Vulnerable Code

python
API_KEY = os.environ.get("IMAGE_GEN_API_KEY", "")
BASE_URL = os.environ.get("IMAGE_GEN_BASE_URL", "https://code.newcli.com/gemini")

def generate_image(prompt: str, model: str = "gemini-3.1-flash-image-2k-16x9", output_path: str = None) -> str:
    """Generate image from text prompt"""
    
    if not API_KEY:
        print("ERROR: IMAGE_GEN_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = f"{BASE_URL}/v1beta/models/{model}:generateContent"
    
    headers = {
        "Content-Type": "application/json",
        "x-goog-api-key": API_KEY,
    }
    
    payload = {
        "contents": [
            {
                "parts": [
                    {"text": prompt}
                ]
            }
        ],
        "generationConfig": {
            "responseModalities": ["IMAGE", "TEXT"],
            "responseMimeType": "text/plain"
        }
    }
    
    print(f"Generating image with model: {model}", file=sys.stderr)
    print(f"Prompt: {prompt[:100]}...", file=sys.stderr)
    
    try:
        with httpx.Client(timeout=120.0) as client:
            response = client.post(url, headers=headers, json=payload)

Technical Analysis

The script constructs the request URL directly from the configurable IMAGE_GEN_BASE_URL value without validating its scheme, hostname, port, or destination. It then transmits the API key in the x-goog-api-key header and the potentially sensitive user prompt in the request body.

The default endpoint is also a third-party relay rather than a documented official Google API endpoint. Consequently, credentials and prompt data are disclosed to that service during normal use. If an attacker can i ...[truncated 1746 chars]

Remediation
View remediation

Remediation Suggestions

  1. Use the official provider endpoint as the default unless use of a relay is an explicitly disclosed requirement.
  2. Parse the configured URL and require HTTPS.
  3. Enforce an explicit allowlist of trusted hostnames and permitted ports before attaching credentials.
  4. Reject URLs containing embedded user information, unexpected ports, fragments, or destinations resolving to loopback, link-local, private, or otherwise prohibited network ranges.
  5. Revalidate redirects or disable them so an approved endpoint cannot redirect a credential-bearing request to an untrusted origin.
  6. Attach x-goog-api-key only after the final destination has passed validation.
  7. Clearly disclose any third-party processing of credentials and prompts in the Skill documentation.
  8. Use narrowly scoped, revocable credentials and rotate any credential that may already have been sent to an untrusted service.
  9. Avoid logging prompt text by default because prompts may contain sensitive information.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:70
Finding

Arbitrary File Overwrite Through an Unrestricted Output Path

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_image.py:70-76 and scripts/generate_image.py:91
Vulnerability Type: Arbitrary file overwrite
Risk Level: Medium

Vulnerable Code

python
if output_path:
    out_file = Path(output_path)
else:
    out_file = Path.cwd() / f"generated_image.{ext}"

out_file.write_bytes(img_bytes)
print(f"Image saved to: {out_file}", file=sys.stderr)

The destination is exposed directly as a command-line argument:

python
parser.add_argument("--output", "-o", help="Output file path")

Technical Analysis

The caller-provided output path is converted directly into a Path and passed to write_bytes. The implementation performs no canonical-path validation, output-directory restriction, symlink check, file-type check, or existing-file protection. Path.write_bytes opens the target for writing and truncates an existing file.

Therefore, any caller able to control --output can overwrite any file writable by the operating-system account running the Skill. The bytes written to the destination are decoded from an external API response, so the final contents are also controlled by the responding service.

Relative traversal paths, absolute paths, and paths resolving through symbolic links are all accepted. Exploitation does not require shell metacharacters because the vulnerability is a direct unsafe file operation rather than command injection.

Attack Path

  1. An attacker supplies or influences an image-generation request containing a chosen --output destination.
  2. The selected destination points to an existing sensitive file, a path outside the intended output directory, or a symbolic link to such a file.
  3. The external image endpoint returns attacker-controlled base64 data in inlineData.
  4. The script decodes the response and invokes out_file.write_bytes(img_bytes).
  5. The target file is created or tru ...[truncated 773 chars]
Remediation
View remediation

Remediation Suggestions

  1. Save generated files only beneath a dedicated, application-controlled output directory.
  2. Resolve both the allowed directory and requested destination to canonical paths and verify that the destination remains inside the allowed directory.
  3. Accept a safe filename rather than an arbitrary filesystem path.
  4. Reject absolute paths, parent-directory traversal, symbolic links, directories, device files, and other non-regular targets.
  5. Use exclusive file creation so existing files are not overwritten by default.
  6. If replacement is required, require an explicit trusted-user confirmation or a separate --force option.
  7. Open files using operating-system protections such as O_CREAT | O_EXCL | O_NOFOLLOW where supported, then write through the securely opened descriptor.
  8. Generate unpredictable filenames when the caller does not need to select a name.
  9. Validate the decoded response size and supported image format before writing it to disk.
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The skill claims to support image-to-image generation, image editing, and style transfer, but the documented behavior only covers prompt-based image generation via a script. This mismatch can mislead users and higher-level agents into sending images or sensitive content under false assumptions, and it undermines security review because the declared scope is broader than the implemented behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documentation indicates capabilities that require environment access, file output, and network access, but it does not declare any explicit tool scope or permissions boundary. This creates an authorization and review gap: an agent may invoke networked code that reads secrets and writes files without the skill manifest clearly constraining or disclosing those actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest description is entirely framed in Chinese and states when the skill should be used, but it does not indicate that language choice is optional or that the skill is intended only for Chinese-language users. This can violate language/locale policy expectations because it implicitly constrains usage to a specific language without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README presents the skill description and setup instructions entirely in Chinese, which can impose a specific language on users without offering an alternative or opt-in. Under the policy rule for language/locale, this is a natural-language policy concern because the skill does not indicate that users may choose another language.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.