Back to skill

Security audit

Grok Imagine Image Pro

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill has a coherent purpose, but it uploads user content to xAI and includes unsafe command examples that could run unintended code if copied with untrusted inputs.

Install only if you are comfortable sending prompts and selected images to xAI. Avoid using it with sensitive images, private documents, or untrusted prompts until the examples are rewritten to pass user inputs as structured data and to use safe temporary 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:26
Finding
Shell Command Injection Through Image-Generation Prompt Interpolation## Vulnerability Details **File Location**: `SKILL.md`, lines 26-46 **Vulnerability Type**: Shell command injection through unsafe interpolation **Risk Level**: High ### Vulnerable Code ```bash curl -s https://api.x.ai/v1/images/generations \ -H "Authorization: Bearer $XAI_API_KEY" \ -H "Content-Type: application/json" \ --data '{ "model": "grok-imagine-image-pro", "prompt": "<PROMPT>", "n": 1, "response_format": "b64_json" }' | python3 -c " import json, sys, base64, os, time os.makedirs(os.path.expanduser('~/.openclaw/media'), exist_ok=True) r = json.load(sys.stdin) ts = int(time.time()) for i, img in enumerate(r['data']): img_data = base64.b64decode(img['b64_json']) fpath = os.path.expanduser(f'~/.openclaw/media/generated_{ts}_{i}.png') with open(fpath, 'wb') as f: f.write(img_data) print(fpath) " ``` ### Technical Analysis The documentation instructs the Agent to substitute a user-supplied image prompt directly into a single-quoted shell argument. No JSON serialization or shell-safe argument handling is applied. If the prompt contains a single quote followed by shell syntax, it can terminate the `--data` argument and introduce additional shell commands. JSON double quotes do not protect the value from shell parsing because the entire JSON document is enclosed in shell single quotes. This is especially dangerous in an Agent Skill because image prompts are expected to originate from users and may therefore be attacker-controlled. ### Attack Path 1. An attacker submits an image-generation request containing a prompt with a single quote, shell separators, and an injected command. 2. The Agent replaces `<PROMPT>` with that content as instructed by the Skill. 3. The injected quote terminates the shell's single-quoted JSON argument. 4. The shell interprets the remaining attacker-controlled content as commands. 5. Those commands ...[truncated 592 chars]
Remediation
## Remediation Suggestions - Do not construct executable shell text by substituting the prompt into a quoted command. - Build the complete request body using a Python script and `json.dump` or `json.dumps`. - Supply the prompt through a non-executable channel, such as a Python argument, standard input, or a narrowly scoped environment variable. - Invoke the HTTP client through `subprocess.run` with an argument array and `shell=False`, or perform the request directly with a vetted HTTP library. - Validate maximum prompt length and reject unexpected control characters. - Run the image-generation process in a restricted environment with minimal filesystem and network access.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:81
Finding
Python Code Injection Through Local Image Path and Edit Prompt## Vulnerability Details **File Location**: `SKILL.md`, lines 81-96 **Vulnerability Type**: Python source-code injection through unsafe interpolation **Risk Level**: High ### Vulnerable Code ```bash python3 -c " import json, base64 with open('<SOURCE_PATH>', 'rb') as f: b64 = base64.b64encode(f.read()).decode() payload = { 'model': 'grok-imagine-image', 'prompt': '<EDIT_PROMPT>', 'image_url': f'data:image/png;base64,{b64}', 'n': 1, 'response_format': 'b64_json' } with open('/tmp/img_edit_payload.json', 'w') as f: json.dump(payload, f) print('Payload ready') " && \ ``` ### Technical Analysis The source path and edit prompt are embedded directly into Python source executed with `python3 -c`. Both values can reasonably be influenced by a user requesting an image edit. An input containing quote characters, newlines, or Python syntax can escape the intended string literal and alter the program executed by the interpreter. There is no separation between data and executable code. Shell quoting adds another parsing layer but does not make direct source interpolation safe. The source-path placeholder also allows unrestricted selection of files readable by the Agent. Although local-file access is necessary for image editing, the Skill provides no validation that the selected path corresponds to an explicitly authorized image. ### Attack Path 1. An attacker supplies a crafted source path or edit prompt containing characters that terminate the Python string literal. 2. The Agent substitutes that value into the documented `python3 -c` program. 3. The Python interpreter parses the injected statements as part of the program. 4. The injected Python code executes before or during construction of the API payload. 5. The attacker can use the Agent's process permissions to access local files, execute subprocesses, inspect environment variables, or initiate network c ...[truncated 537 chars]
Remediation
## Remediation Suggestions - Place the Python logic in a fixed script rather than generating Python source dynamically. - Pass the source path and edit prompt as ordinary command-line arguments to the fixed script, or provide them through standard input as structured JSON. - Use `json.dump` to serialize all attacker-controlled values. - If launching the script from another process, use an argument array and disable shell interpretation. - Resolve the requested path with `Path.resolve()` and require it to be inside explicitly approved media directories. - Reject symbolic links and non-regular files where they are not required. - Require explicit user authorization before reading and uploading any local file. - Apply file-size and supported-format limits before loading a source image into memory.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:113
Finding
Shell Command Injection Through Public Image URL Interpolation## Vulnerability Details **File Location**: `SKILL.md`, lines 113-123 **Vulnerability Type**: Shell command injection through unsafe URL interpolation **Risk Level**: High ### Vulnerable Code ```bash curl -s https://api.x.ai/v1/images/generations \ -H "Authorization: Bearer $XAI_API_KEY" \ -H "Content-Type: application/json" \ --data '{ "model": "grok-imagine-image", "prompt": "<EDIT_PROMPT>", "image_url": "<PUBLIC_IMAGE_URL>", "n": 1, "response_format": "b64_json" }' | python3 -c " ``` ### Technical Analysis Both `<EDIT_PROMPT>` and `<PUBLIC_IMAGE_URL>` are inserted into a JSON document enclosed in shell single quotes. A user-controlled apostrophe can close the shell argument, after which shell metacharacters can introduce arbitrary commands. The URL is not passed directly to `curl` as a URL argument; it is still unsafe because it is interpolated into shell source. The Skill also documents no scheme or length validation for this value. ### Attack Path 1. An attacker requests an edit using a crafted public image URL or edit prompt. 2. The supplied value contains a single quote that terminates the shell-quoted request body. 3. Additional attacker-controlled shell syntax is parsed as a command. 4. The command runs in the Agent's execution environment. 5. The attacker may read credentials, modify files, or make unauthorized outbound requests. ### Impact Assessment The vulnerability enables arbitrary command execution with the Agent account's privileges. Potential consequences include theft of API credentials, access to local media or configuration files, unauthorized network activity, and modification or destruction of Agent-accessible data. The behavior exceeds the minimum privileges required to submit a public image URL to an image-generation API.
Remediation
## Remediation Suggestions - Construct the request using a structured serializer rather than shell interpolation. - Pass the prompt and URL to a fixed program as data, not as executable shell text. - Use an HTTP library or `subprocess.run([...], shell=False)`. - Permit only necessary schemes, normally `https`, and reject control characters and excessive URL lengths. - Consider applying an allowlist of trusted image hosts if compatible with the intended functionality. - Ensure logs and error messages do not expose the authorization header.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:84
Finding
Predictable Temporary Payload File Exposes Image Data and Permits Symlink Attacks## Vulnerability Details **File Location**: `SKILL.md`, lines 84-100 **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```bash with open('<SOURCE_PATH>', 'rb') as f: b64 = base64.b64encode(f.read()).decode() payload = { 'model': 'grok-imagine-image', 'prompt': '<EDIT_PROMPT>', 'image_url': f'data:image/png;base64,{b64}', 'n': 1, 'response_format': 'b64_json' } with open('/tmp/img_edit_payload.json', 'w') as f: json.dump(payload, f) print('Payload ready') " && \ curl -s https://api.x.ai/v1/images/generations \ -H "Authorization: Bearer $XAI_API_KEY" \ -H "Content-Type: application/json" \ -d @/tmp/img_edit_payload.json ``` ### Technical Analysis The code writes the complete base64-encoded source image and edit prompt to the fixed path `/tmp/img_edit_payload.json`. It neither creates the file atomically nor removes it after use. In a shared temporary directory, another local process may predict the path and create a symbolic link before execution. Because ordinary `open(..., 'w')` follows symbolic links, the Agent could truncate and overwrite another file writable by its account. Repeated or concurrent Skill invocations also use the same file and can overwrite or mix each other's request payloads. The payload remains on disk after the API request. Base64 is an encoding and provides no confidentiality, so any process able to read the file can recover the source image and prompt. The encoding itself is necessary for the declared API format and is not evidence of a covert channel; the unsafe persistent temporary storage is the security defect. ### Attack Path 1. A local attacker predicts the fixed `/tmp/img_edit_payload.json` path. 2. The attacker creates a symbolic link at that location pointing to another file writable by the Agent, or waits to read the generated payload. 3. The Agent performs an ...[truncated 755 chars]
Remediation
## Remediation Suggestions - Avoid writing the payload to disk where possible; send serialized JSON through standard input or directly through an HTTP library. - If a temporary file is necessary, create it atomically with Python's `tempfile.NamedTemporaryFile` or `mkstemp`. - Restrict file permissions to `0600`. - Keep the temporary file open while it is used where platform behavior permits. - Delete the file in a `finally` block immediately after the request, including when the request fails. - Do not reuse a fixed filename across requests. - Reject symbolic links and ensure the temporary directory is trusted and access-controlled.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (10)

External Script Fetching

High
Category
Supply Chain
Content
env:
        - XAI_API_KEY
      bins:
        - curl
        - python3
---
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
**Do NOT use `/v1/images/edits` with multipart — xAI requires JSON.**

**IMPORTANT:** For local files, use Python to build the payload JSON file, then curl with `@file`.
Inline base64 in curl args causes "Argument list too long" for images >~100KB.

**NOTE:** This is NOT true image editing — the API generates a new image inspired by the source.
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
### Edit from URL:

```bash
curl -s https://api.x.ai/v1/images/generations \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Transmission

Medium
Category
Data Exfiltration
Content
env:
        - XAI_API_KEY
      bins:
        - curl
        - python3
---
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## 1. Image Generation

```bash
curl -s https://api.x.ai/v1/images/generations \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## 1. Image Generation

```bash
curl -s https://api.x.ai/v1/images/generations \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly supports sending local images and prompts to xAI for editing/generation, but it does not clearly warn the user that local file contents and text prompts are transmitted to a third-party external API. This can lead to unintended disclosure of sensitive personal, proprietary, or regulated image data when users believe processing is local.

External Transmission

Medium
Category
Data Exfiltration
Content
**Do NOT use `/v1/images/edits` with multipart — xAI requires JSON.**

**IMPORTANT:** For local files, use Python to build the payload JSON file, then curl with `@file`.
Inline base64 in curl args causes "Argument list too long" for images >~100KB.

**NOTE:** This is NOT true image editing — the API generates a new image inspired by the source.
Confidence
89% confidence
Finding
This section instructs the agent to package a local image into base64 and send it to xAI, creating a real external data exfiltration path for local file contents. In context, the issue is not that transmission exists, but that the skill lacks strong consent and sensitivity checks before uploading potentially private local images.

External Transmission

Medium
Category
Data Exfiltration
Content
json.dump(payload, f)
print('Payload ready')
" && \
curl -s https://api.x.ai/v1/images/generations \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d @/tmp/img_edit_payload.json | python3 -c "
Confidence
92% confidence
Finding
This command uploads a JSON payload containing a base64-encoded local image to xAI, which is a concrete external transfer of local data. Without explicit user warning and confirmation, the skill can unintentionally disclose sensitive images or documents converted into image form.

External Transmission

Medium
Category
Data Exfiltration
Content
### Edit from URL:

```bash
curl -s https://api.x.ai/v1/images/generations \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.