Back to skill

Security audit

Cloudflare Image Generation

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real Cloudflare image generator, but it exposes a Cloudflare token and lets crafted prompts reach shell execution, so it needs review before installation.

Review before installing. The publisher should remove and rotate the exposed Cloudflare token, load credentials from user-controlled secret storage, replace shell-based curl with a native HTTPS client or shell=False argument list, avoid fixed temp files, and document exactly where images are saved and what data is sent to Cloudflare.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_image.py:11
Finding

Hardcoded Cloudflare API Credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_image.py:22
Finding

Arbitrary Shell Command Injection Through the Image Prompt

Content
View full analysis
/tmp/cf_response.json''' subprocess.run(cmd, shell=True) ``` ### Technical Analysis The caller-controlled `prompt` is serialized as JSON and then interpolated into a command string executed with `shell=True`. JSON serialization escapes JSON syntax but does not make content safe for inclusion in a POSIX shell command. The JSON document is placed inside a single-quoted shell argument. A single quote supplied in the prompt can terminate that shell quoting context. Subsequent shell metacharacters can introduce additional commands, pipelines, redirections, or substitutions. The shell then executes the injected content with the same operating-system identity and permissions as the Skill process. The program does not need a shell for this API request. Constructing a shell command therefore creates an avoidable code-execution boundary. ### Attack Path 1. An attacker supplies an image-generation prompt containing a single quote followed by shell syntax. 2. `json.dumps()` produces valid JSON, but the attacker-controlled single quote remains significant to the shell. 3. The prompt is interpolated into the single-quoted `curl -d` argument. 4. The injected single quote terminates the intended shell argument. 5. Attacker-controlled shell operators cause an additional command to execute. 6. `subprocess.run(..., shell=True)` launches the shell and executes both the intended command fragment and the injected command. 7. The injected process inherits the Skill process's user privileges and accessible environment. ### Impact Assessment An attacker who can co ...[truncated 655 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_image.py:22
Finding

Predictable Shared Temporary File Enables Symlink Clobbering and Response Races

Content
View full analysis
/tmp/cf_response.json''' subprocess.run(cmd, shell=True) with open('/tmp/cf_response.json', 'r') as f: data = json.load(f) ``` ### Technical Analysis Every invocation writes its response to the fixed path `/tmp/cf_response.json`. Shared temporary directories are commonly writable by multiple local users or processes. Shell redirection opens the destination before `curl` runs and follows symbolic links. A local attacker can pre-create `/tmp/cf_response.json` as a symbolic link to another file writable by the Skill's operating-system account. The shell redirection may then truncate and overwrite that target. The predictable name also introduces a time-of-check/time-of-use race: an attacker or concurrent invocation can replace or rewrite the response before the program reads it. Concurrent legitimate invocations use the same file as well, allowing one request to consume another request's response. The file is not removed after use, so API response data also remains in a globally predictable location. ### Attack Path **Symlink clobbering:** 1. A local attacker creates `/tmp/cf_response.json` as a symbolic link to a chosen file. 2. The attacker causes or waits for the Skill to generate an image. 3. Shell redirection follows the symbolic link and opens the target for truncation. 4. The Cloudflare response is written into the target using the Skill process's filesystem privileges. 5. The selected file is corrupted or replaced with response data. **Response substitution or race:** 1. The attacker monitors or repeatedly replaces the pred ...[truncated 841 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:22
Finding

Bearer Token Disclosed Through Spawned Process Command Lines

Content
View full analysis
/tmp/cf_response.json''' subprocess.run(cmd, shell=True) ``` ### Technical Analysis The bearer token is embedded in a shell command and then passed to a spawned process. The command is exposed as part of the shell invocation, and the authorization header is subsequently passed as a command-line argument to `curl`. Depending on operating-system process visibility, container isolation, diagnostic tooling, monitoring agents, crash collection, and logging configuration, other users or services may be able to inspect process command lines. This exposes the bearer token beyond the Python process that legitimately needs it. This finding is distinct from hardcoding: even after moving the token to an environment variable or secret manager, inserting it into this command string would continue to expose it through process metadata. ### Attack Path 1. An attacker obtains local process-inspection access or access to process telemetry. 2. The attacker monitors processes while image generation is running. 3. The attacker captures the shell or `curl` command line containing the `Authorization: Bearer ...` header. 4. The attacker extracts the token. 5. The attacker replays the token directly against Cloudflare APIs until it expires or is revoked. ### Impact Assessment The attacker obtains the same Cloudflare API permissions granted to the stolen token. Likely effects include unauthorized AI requests, quota consumption, billing abuse, and service disruption. Broader effects depend on the token's unknown server-side scopes. Exploitability ...[truncated 202 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to only generate images, but the content also exposes a hardcoded Cloudflare API token and account ID, writes files locally, and references direct script execution. This mismatch is dangerous because reviewers or automated policy systems may trust the benign description while overlooking sensitive credential exposure and broader execution behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
100% confidence
Finding

The markdown directly includes a live-looking API token and account identifier without any masking or secure-handling guidance. Exposed credentials can be immediately reused by anyone with access to the skill, enabling unauthorized API calls, abuse of the Cloudflare account, cost incurrence, and possible downstream compromise of connected resources.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

An image-generation skill only needs to make an HTTP request, but this implementation adds general shell execution capability through curl and shell=True. In this context, that is unnecessarily dangerous because it expands the skill from simple network use into arbitrary command execution if the prompt or command construction is abused.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A live API bearer token is hardcoded directly in the script and used for outbound requests, which exposes a secret to anyone with code access and makes accidental leakage or misuse highly likely. If reused elsewhere or committed to a repository, an attacker could abuse the Cloudflare account, incur cost, or access associated services.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script constructs and executes a shell command from user input without adequate safeguards or disclosure, creating a direct path to command injection. In a skill context, prompts are expected to be attacker-controlled, so treating them as safe command-string content is especially dangerous.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

This is a concrete tool-parameter abuse issue: attacker-controlled prompt data is funneled into a shell-executed command, allowing the tool boundary to be crossed from 'generate an image' into 'run arbitrary OS commands'. In agent skills, this context makes the issue more dangerous because natural-language inputs are routinely untrusted and can be adversarially crafted.

Content

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

python
-H "Content-Type: application/json" \
      -d '{json.dumps({"prompt": prompt})}' > /tmp/cf_response.json'''
    
    subprocess.run(cmd, shell=True)
    
    with open('/tmp/cf_response.json', 'r') as f:
        data = json.load(f)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill declares no explicit tool scope even though its documented usage clearly implies shell execution and file access. In an agent environment, missing scope declarations weaken sandboxing and review controls, making it easier for the skill to use capabilities beyond what operators expect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill writes API responses to a fixed temporary file and saves generated images to a local workspace path by default, creating local persistence not clearly implied by the stated behavior. This increases exposure because sensitive prompts, generated content, or API responses may remain on disk, and the fixed /tmp/cf_response.json path is susceptible to collisions or tampering in shared environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The function derives a default filesystem path and writes the generated image there, but the code provides no prior disclosure that it will create a file in the workspace by default. The save location is only printed after completion, which does not warn the user before the write occurs.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

python
output_path = f"/home/ubuntu/.openclaw/workspace/{prompt.replace(' ', '_')[:30]}.png"
    
    # Call Cloudflare API
    cmd = f'''curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/run/{MODEL}" \
      -H "Authorization: Bearer {TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{json.dumps({"prompt": prompt})}' > /tmp/cf_response.json'''

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

python
output_path = f"/home/ubuntu/.openclaw/workspace/{prompt.replace(' ', '_')[:30]}.png"
    
    # Call Cloudflare API
    cmd = f'''curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/run/{MODEL}" \
      -H "Authorization: Bearer {TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{json.dumps({"prompt": prompt})}' > /tmp/cf_response.json'''

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The script builds a shell command containing user-controlled input (prompt) and executes it with shell=True, which creates a command-injection path. Even though json.dumps escapes JSON syntax, it does not make shell interpolation safe; a crafted prompt containing shell-significant characters can break quoting and execute arbitrary commands on the host.

Content

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

python
-H "Content-Type: application/json" \
      -d '{json.dumps({"prompt": prompt})}' > /tmp/cf_response.json'''
    
    subprocess.run(cmd, shell=True)
    
    with open('/tmp/cf_response.json', 'r') as f:
        data = json.load(f)

Static analysis

No suspicious patterns detected.