Back to skill

Security audit

Codex Imggen

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill is not plainly malicious, but it should be reviewed carefully because it runs user-supplied image text through a general-purpose Codex agent and may send prompts or reference images outside the machine without strong containment.

Install only if you are comfortable letting this skill invoke Codex CLI on your prompts and optional reference images. Avoid using confidential prompts, private artwork, internal screenshots, regulated data, or sensitive local image files unless your Codex account, proxy, sandbox, and data-handling policy are approved. Prefer running it in a restricted, disposable workspace and verify outputs because the copy step can pick the newest shared Codex image directory rather than a guaranteed current-session result.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
scripts/generate.sh:41
Finding
User-Controlled Image Descriptions Are Executed as Codex Agent Instructions<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/generate.sh:41-45` - `scripts/gen_size.sh:83-93` - `scripts/batch_generate.sh:40-50` **Vulnerability Type**: Prompt injection into a general-purpose agent **Risk Level**: High ### Vulnerable Code `scripts/generate.sh:41-45`: ```bash if [[ -n "$REF_IMAGE" ]]; then codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1 else codex exec --skip-git-repo-check -- "$PROMPT" 2>&1 fi ``` `scripts/gen_size.sh:83-93`: ```bash PROMPT="Generate a $SIZE_DESC. Subject: $SUBJECT. Solid background with the subject centered and clearly visible. High quality, clean rendering." echo "Generating: size=$SIZE_KEY, subject=$SUBJECT" export http_proxy="$PROXY" https_proxy="$PROXY" if [[ -n "$REF_IMAGE" ]]; then codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1 else codex exec --skip-git-repo-check -- "$PROMPT" 2>&1 fi ``` `scripts/batch_generate.sh:40-50`: ```bash PROMPT="Generate a set of ${COUNT} game UI elements, all sharing the exact same visual style: ${STYLE_PROMPT}. Each element should be on a white background (#ffffff), with consistent lighting, consistent border thickness, and consistent padding. Generate ONE single combined image containing all ${COUNT} items arranged in a clean grid (e.g., 3x2 or 2x3 layout). Make each individual element approximately 512x512 pixels in the final combined image." echo "Generating batch: $COUNT items, style: $STYLE_PROMPT" export http_proxy="$PROXY" https_proxy="$PROXY" if [[ -n "$REF_IMAGE" ]]; then codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1 else codex exec --skip-git-repo-check -- "$PROMPT" 2>&1 fi ``` ### Technical Analysis The scripts pass caller-controlled values—`PROMPT`, `SUBJECT`, and `STYLE_PROMPT`—directly to `codex exec`. Codex is a general-purpose coding agent rather than a narrowly constrained image-generation interface. Consequently, the supplied image description is interpreted as an ag ...[truncated 2069 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `codex exec` with a dedicated image-generation API that accepts structured image parameters and does not expose general-purpose agent tools. 2. If Codex must remain in use, run it inside a restrictive sandbox with: - No shell or arbitrary command-execution capability. - No access to user files, credentials, SSH keys, tokens, or unrelated workspaces. - Network access restricted to explicitly required image-generation endpoints. - A disposable working directory and a dedicated low-privilege operating-system account. 3. Apply a fixed, non-overridable instruction that treats the caller's text strictly as image-description data. This is defense in depth and must not replace capability isolation. 4. Validate prompt length and reject content that requests tool use, file access, command execution, credential access, policy changes, or unrelated tasks. 5. Require explicit approval before exposing reference images or enabling any operation outside image generation. 6. Log the effective sandbox and tool policy, and fail closed when the required restricted execution profile cannot be verified. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate.sh:47
Finding
Global Latest-Directory Selection Can Copy Stale or Concurrent Session Images<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/generate.sh:47-51` - `scripts/gen_size.sh:95-99` - `scripts/batch_generate.sh:52-56` **Vulnerability Type**: Insecure shared-output selection and session isolation **Risk Level**: Medium ### Vulnerable Code `scripts/generate.sh:47-51`: ```bash latest=$(ls -t ~/.codex/generated_images/ 2>/dev/null | head -1) if [[ -n "$latest" ]]; then cp ~/.codex/generated_images/$latest/*.png "$OUTDIR/" 2>/dev/null echo "Saved to $OUTDIR/" fi ``` `scripts/gen_size.sh:95-99`: ```bash latest=$(ls -t ~/.codex/generated_images/ 2>/dev/null | head -1) if [[ -n "$latest" ]]; then cp ~/.codex/generated_images/$latest/*.png "$OUTDIR/output.png" 2>/dev/null echo "Saved to $OUTDIR/output.png" fi ``` `scripts/batch_generate.sh:52-56`: ```bash latest=$(ls -t ~/.codex/generated_images/ 2>/dev/null | head -1) if [[ -n "$latest" ]]; then cp ~/.codex/generated_images/$latest/*.png "$OUTDIR/batch.png" 2>/dev/null echo "Batch saved to $OUTDIR/batch.png" fi ``` ### Technical Analysis After invoking Codex, every script searches the shared `~/.codex/generated_images/` directory and selects whichever entry has the newest modification timestamp. The code does not establish that this directory was created by the current invocation. This creates a session-confusion and race-condition weakness. If the current command does not produce an image, a prior session's directory may remain the newest and its files may be copied. If another Codex process produces output concurrently, that process's session may become the newest before the lookup occurs. The scripts can therefore return unrelated content while reporting it as the current result. The unquoted source path also permits pathname expansion and word splitting. Although the expected session names may normally be controlled by Codex, robust code should not rely on undocumented naming constraints for paths read from a shared directory. ### Attack Path 1. A prior or ...[truncated 1282 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Obtain the exact output path or session identifier from the current `codex exec` invocation and copy only from that path. 2. If Codex cannot return an output identifier: - Record the existing session directories before execution. - Run Codex. - Identify directories newly created by that invocation. - Require exactly one unambiguous new session and fail closed otherwise. 3. Use a per-invocation output directory if the CLI supports one, preferably beneath the already-created private temporary directory. 4. Verify that the selected source is a real directory under the expected canonical base path and is not a symbolic link. 5. Quote all path expansions, for example: ```bash cp "$HOME/.codex/generated_images/$session/"*.png "$OUTDIR/" ``` 6. Avoid parsing `ls`; use shell arrays, `find` with explicit constraints, or machine-readable CLI output. 7. Do not suppress copy errors with `2>/dev/null`. Report missing, multiple, or ambiguous outputs and return a nonzero status. 8. Apply restrictive permissions to generated-image directories where multiple users or processes may share an environment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
代码的核心目的仍然是通过 Codex CLI 生成图片,这一点与声明基本一致;默认代理启用也与声明相符。但声明中列出的若干功能在该代码片段里并未实现,尤其是尺寸控制和批量模式。更重要的是,代码实际支持一个未声明的重要能力:通过 -i/--ref-image 传入参考图片进行生成。此外,声明说所有输出保存到 ~/.codex/generated_images/,而脚本还会把生成的 PNG 复制到用户指定目录,因此资源/输出位置描述也不完全准确。综合来看,描述未能准确反映该代码片段的实际行为,属于不匹配。

External Model or Provider Selection

High
Category
Excessive Agency
Content
export http_proxy="$PROXY" https_proxy="$PROXY"

if [[ -n "$REF_IMAGE" ]]; then
  codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1
else
  codex exec --skip-git-repo-check -- "$PROMPT" 2>&1
fi
Confidence
92% confidence
Finding
When `-i/--ref-image` is used, the script uploads a local file to an external AI provider without any trust boundary enforcement or explicit consent workflow. This is more dangerous in this skill because reference images can contain proprietary art, internal UI mockups, or personal data, and the script is specifically designed to batch process user-supplied creative assets.

External Model or Provider Selection

High
Category
Excessive Agency
Content
if [[ -n "$REF_IMAGE" ]]; then
  codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1
else
  codex exec --skip-git-repo-check -- "$PROMPT" 2>&1
fi

latest=$(ls -t ~/.codex/generated_images/ 2>/dev/null | head -1)
Confidence
90% confidence
Finding
Even without a reference image, `codex exec` sends the constructed prompt to an external model/provider, which can expose sensitive project descriptions, unreleased product details, or proprietary design requirements. In this image-generation skill, users are encouraged to provide rich style prompts, increasing the chance that confidential context is embedded in the transmitted text.

External Model or Provider Selection

High
Category
Excessive Agency
Content
export http_proxy="$PROXY" https_proxy="$PROXY"

if [[ -n "$REF_IMAGE" ]]; then
  codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1
else
  codex exec --skip-git-repo-check -- "$PROMPT" 2>&1
fi
Confidence
91% confidence
Finding
When a reference image is supplied, the script sends both the prompt and the local file path/content to an external model provider via `codex exec -i`. In a skill context, this is dangerous because users may pass sensitive local images without realizing they are being transmitted off-host, and the script also enables proxying by default, expanding the data exposure surface.

External Model or Provider Selection

High
Category
Excessive Agency
Content
if [[ -n "$REF_IMAGE" ]]; then
  codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1
else
  codex exec --skip-git-repo-check -- "$PROMPT" 2>&1
fi

latest=$(ls -t ~/.codex/generated_images/ 2>/dev/null | head -1)
Confidence
90% confidence
Finding
Even without a reference image, the script forwards user-supplied prompts to an external model provider using `codex exec`, which can leak confidential text or internal project context if the skill is used in sensitive environments. The risk is heightened by the skill’s automation framing and default proxy support, which may obscure where data is sent.

External Model or Provider Selection

High
Category
Excessive Agency
Content
export http_proxy="$PROXY" https_proxy="$PROXY"

if [[ -n "$REF_IMAGE" ]]; then
  codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1
else
  codex exec --skip-git-repo-check -- "$PROMPT" 2>&1
fi
Confidence
90% confidence
Finding
Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

External Model or Provider Selection

High
Category
Excessive Agency
Content
if [[ -n "$REF_IMAGE" ]]; then
  codex exec -i "$REF_IMAGE" --skip-git-repo-check -- "$PROMPT" 2>&1
else
  codex exec --skip-git-repo-check -- "$PROMPT" 2>&1
fi

latest=$(ls -t ~/.codex/generated_images/ 2>/dev/null | head -1)
Confidence
90% confidence
Finding
Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill documents optional reference-image input and states that a proxy is enabled by default, but it does not warn users that supplied images and prompts may be transmitted to external services, potentially through a local proxy. This can lead to inadvertent disclosure of sensitive images, metadata, or proprietary assets because users may assume the operation is local-only.

Session Persistence

Medium
Category
Rogue Agent
Content
WORKDIR=$(mktemp -d)
cd "$WORKDIR" && git init -q
mkdir -p "$OUTDIR"

PROMPT="Generate a set of ${COUNT} game UI elements, all sharing the exact same visual style: ${STYLE_PROMPT}. Each element should be on a white background (#ffffff), with consistent lighting, consistent border thickness, and consistent padding. Generate ONE single combined image containing all ${COUNT} items arranged in a clean grid (e.g., 3x2 or 2x3 layout). Make each individual element approximately 512x512 pixels in the final combined image."
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script sends the prompt and optional reference image to an external service via `codex exec`, and explicitly enables proxy routing through `http_proxy`/`https_proxy`. In a skill context, users may provide sensitive prompts or local image files without realizing that both content and metadata may leave the local machine and transit a proxy or remote provider.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest states that all outputs are saved to ~/.codex/generated_images/, but this script accepts an arbitrary output directory and defaults to '.' when none is provided. It later copies the generated PNG into that caller-controlled location, so the effective output behavior extends beyond the manifest's described storage location.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
Rather than only relying on Codex's output directory, the script enumerates ~/.codex/generated_images/ and copies the newest PNG to $OUTDIR/output.png. This means the skill does more than simply save outputs in ~/.codex/generated_images/ as described; it also redistributes them to other filesystem locations.

Session Persistence

Medium
Category
Rogue Agent
Content
WORKDIR=$(mktemp -d)
cd "$WORKDIR" && git init -q
mkdir -p "$OUTDIR"

export http_proxy="$PROXY" https_proxy="$PROXY"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
L120 的注释称应使用 `batch_split.py`,但 L121 实际给出的却是 `python3 .../batch_split.sh`。这是文档内部对所用脚本类型和调用方式的直接矛盾,容易误导使用者执行错误命令。

Missing User Warnings

Low
Confidence
79% confidence
Finding
This shell script performs a file write by copying a PNG into the target output directory. While it later prints that the batch was saved, there is no prior warning, confirmation, or inline comment/doc text disclosing that it will write or overwrite output content at the specified path.

Missing User Warnings

Low
Confidence
87% confidence
Finding
The script invokes `codex exec`, which is a subprocess operation and likely sends the user-provided prompt and optional reference image to an external service or agent workflow. While the script prints a generic generation message, it does not clearly disclose that content may be externally processed or that a shell-level tool is being executed.

Static analysis

No suspicious patterns detected.