Back to skill

Security audit

Google vertex image generator

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill is mostly aligned with its stated purpose, but it handles Google tokens and response-supplied URLs in a way that could expose credentials or leave sensitive data behind.

Review before installing. Use only with low-privilege Google Cloud credentials and non-sensitive prompts unless the URL download path is constrained to trusted Google endpoints and bearer tokens are never sent to arbitrary response URLs. The skill should also stop retaining full API responses by default or make debug logging explicit and cleaned up.

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/image_harness.py:92
Finding

Google OAuth Bearer Token Disclosed to Untrusted Response-Supplied URLs

Content
View full analysis
bool: cmd = ['curl', '-sS', '-L', uri, '-o', out_path] if token: cmd[1:1] = ['-H', f'Authorization: Bearer {token}'] proc = subprocess.run(cmd, capture_output=True) return proc.returncode == 0 ``` ```python def find_uris(obj): uris = [] if isinstance(obj, dict): for k, v in obj.items(): if isinstance(v, str) and (k.lower().endswith('uri') or v.startswith('http')): uris.append(v) elif isinstance(v, (dict, list)): uris.extend(find_uris(v)) elif isinstance(obj, list): for item in obj: uris.extend(find_uris(item)) return uris uris = find_uris(j) if uris: tmp_out = out_path + '.tmp' ok = download_uri(uris[0], tmp_out, token=token) ``` ### Technical Analysis The script recursively treats every HTTP string, and every string stored under a key ending in `uri`, as a potential image URL. It does not validate the URL scheme, destination hostname, port, or relationship to an approved Google service. The selected URL is passed to `curl` together with a live Google OAuth bearer token. When the URL directly identifies an attacker-controlled server, the bearer token is transmitted in the `Authorization` request header. The use of `-L` also enables redirects, although curl's handling of authorization headers across a cross-origin redirect depends on its version and redirect security behavior. A response-supplied URL should be considered untrusted. The broad URL discovery logic may select metadata, citations, model-generated links, or other non-image URLs. Attaching privileged credentials to such a destination exceeds the minimum permissi ...[truncated 1594 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/image_harness.py:159
Finding

Full API Responses Persist Indefinitely in Temporary Files

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description says it uses ADC, but it also supports a separate user-token authentication mode and may download response-derived URLs with curl. This mismatch matters because users may grant trust based on the narrower declared behavior, while the actual implementation expands credential usage and network reach, increasing the chance of unintended token use, SSRF-like fetches, or retrieval of untrusted content.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code adds a generic network-fetch path by following arbitrary HTTP(S) URIs found in the model response. In skill context, this is more dangerous because the skill holds cloud credentials; a crafted response could trigger SSRF to internal services or exfiltrate the bearer token by causing an authenticated request to an attacker-controlled URL.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The manifest describes a skill that generates images via Vertex AI using ADC, which implies authenticated API access, but this implementation depends on spawning external programs (gcloud and curl) to obtain tokens and make requests. Invoking subprocesses is a distinct capability not justified by the manifest description itself and expands the execution surface beyond ordinary API client behavior.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/image_harness.py (reported line 42)May include surrounding context.

python
# 将参数列表安全传递给 subprocess,禁止 shell=True
    full_cmd = base_cmd + list(args)
    return subprocess.run(full_cmd, capture_output=True, text=True)

def get_token(auth_mode: str) -> str:
    args = ['application-default', 'print-access-token'] if auth_mode == 'adc' else ['print-access-token']

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

This subprocess call fetches a URI extracted from the model/API response with curl and optionally includes the bearer token in the Authorization header. That creates a server-side request forgery capability and may leak the ADC access token to an attacker-controlled endpoint if the response can be influenced, which is especially dangerous in a cloud environment.

Content

Scanner excerpt · scripts/image_harness.py (reported line 92)May include surrounding context.

python
cmd = ['curl', '-sS', '-L', uri, '-o', out_path]
    if token:
        cmd[1:1] = ['-H', f'Authorization: Bearer {token}']
    proc = subprocess.run(cmd, capture_output=True)
    return proc.returncode == 0

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file contains natural-language comments in Chinese, which imposes a specific language choice on maintainers and reviewers without offering an alternative or documenting that constraint. Under the stated policy, forcing a specific language without user opt-in is a locale/language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This script writes generated content to the user-specified output path and may overwrite the final target via os.replace, but it does not provide any confirmation prompt or explicit user-facing warning at the point of the file operation. While file output is part of the harness behavior, the code itself lacks disclosure around the write/replace action.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.