Back to skill

Security audit

Image Prompt

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local image-prompt helper that is coherent with its purpose, but users should know it stores prompt text and command history in plaintext local files.

Install only if you are comfortable with prompt text and command history being saved locally under ~/.image-prompt or IMAGE_PROMPT_DIR. Avoid entering confidential prompts on shared machines unless you restrict permissions or clear the history files, and be aware that unusual prompt names containing regex or newline characters could corrupt the local prompt library.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:522
Finding
Regex Injection in Prompt Name Matching Can Remove Unrelated Records<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh:522-529` **Vulnerability Type**: Regex injection and unsafe file update **Risk Level**: Medium ### Vulnerable Code ```bash # Check for duplicate name if grep -q "^${name}|" "$PROMPTS_FILE" 2>/dev/null; then echo "⚠️ A prompt named '$name' already exists. Overwriting." local tmp tmp=$(grep -v "^${name}|" "$PROMPTS_FILE") echo "$tmp" > "$PROMPTS_FILE" fi echo "${name}|${prompt}" >> "$PROMPTS_FILE" ``` ### Technical Analysis The user-controlled `name` value is interpolated directly into a Basic Regular Expression passed to `grep`. Regex metacharacters such as `.`, `*`, `[`, `]`, `^`, and `$` are not escaped. Consequently, a supplied name can match records other than the intended exact prompt name. The same injected expression is used by `grep -v` when rebuilding the prompt database, causing all matching records to be removed. The update is also non-atomic: the complete database is captured in a shell variable and then rewritten directly. An interruption during the rewrite can leave the file incomplete. ### Attack Path 1. Populate `prompts.txt` with multiple records, including names beginning with a common prefix such as `alpha` and `archive`. 2. Invoke the save command with a regex-bearing name: ```bash image-prompt save 'a.*' 'replacement prompt' ``` 3. The duplicate check evaluates the pattern `^a.*|`, which matches multiple existing records rather than one literal name. 4. `grep -v` removes every matching record while retaining nonmatching records. 5. The script rewrites the database and appends the attacker-supplied record. 6. Unrelated saved prompts matching the injected expression are lost. ### Impact Assessment Exploitation is limited to the invoking user's configured prompt database. It can delete or corrupt unrelated saved prompt records but does not grant additional operating-system privileges, execute commands, or access remote systems. The im ...[truncated 131 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not use attacker-controlled values as regular expressions. - Validate prompt names against a restrictive format, such as: ```bash if [[ ! "$name" =~ ^[A-Za-z0-9._-]+$ ]]; then printf '%s\n' "Invalid prompt name" >&2 return 1 fi ``` - Compare the first field literally instead of interpolating it into `grep`: ```bash awk -F '|' -v target="$name" '$1 != target' "$PROMPTS_FILE" ``` - Write updates to a secure temporary file in the same directory and atomically rename it: ```bash tmp_file=$(mktemp "$DATA_DIR/prompts.XXXXXX") awk -F '|' -v target="$name" '$1 != target' "$PROMPTS_FILE" > "$tmp_file" printf '%s|%s\n' "$name" "$prompt" >> "$tmp_file" mv -- "$tmp_file" "$PROMPTS_FILE" ``` - Install a trap to remove the temporary file if the operation is interrupted. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:529
Finding
Delimiter and Newline Injection in Prompt Storage and History Logs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh:529-531` **Vulnerability Type**: Structured-record injection and log forging **Risk Level**: Medium ### Vulnerable Code ```bash echo "${name}|${prompt}" >> "$PROMPTS_FILE" echo "✅ Saved prompt '$name'" _log "save" "$name: $prompt" ``` The logging function writes the supplied value without encoding: ```bash _log() { echo "$(date '+%Y-%m-%d %H:%M:%S') [$1] $2" >> "$HISTORY_LOG" } ``` ### Technical Analysis The prompt database uses a line-oriented `name|prompt` format, but neither field is validated or encoded before storage. An input containing a newline can create additional physical records, while a `|` in the name changes field boundaries when `cmd_list` and `cmd_search` parse the file. The same untrusted input is included in `history.log`. Embedded newline characters can forge additional log entries or make attacker-controlled text appear to be an independent event. Using `echo` also introduces implementation-dependent handling for some values beginning with options or containing escape sequences. ### Attack Path 1. Invoke the command with a name or prompt containing embedded newlines and delimiters. For example: ```bash image-prompt save $'normal\nforged' $'first prompt\nadmin-entry|forged prompt' ``` 2. The script appends the values directly to `prompts.txt`. 3. The embedded newlines create multiple physical lines, and the `|` delimiter causes one injected line to resemble a valid stored prompt. 4. Subsequent `list` or `search` operations process the forged line as an independent record. 5. `_log` writes the same multiline content to `history.log`, allowing misleading or fabricated-looking log lines to be inserted. ### Impact Assessment An attacker able to invoke the Skill can corrupt the invoking user's prompt library and forge entries in its local history log. This may mislead users or downstream tooling that treats each line as a trusted record. The issue d ...[truncated 241 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Reject control characters, including carriage returns and newlines, in prompt names. - Disallow the `|` delimiter in names, or stop using an ad hoc delimiter-based format. - Store records in a structured format such as JSON with correct escaping. - If the current format must be retained, encode both fields before writing and decode them only during display. - Normalize log data by replacing newline and carriage-return characters with escaped representations. - Replace `echo` with `printf`: ```bash printf '%s|%s\n' "$name" "$prompt" >> "$PROMPTS_FILE" printf '%s [%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$event" "$sanitized_message" >> "$HISTORY_LOG" ``` - Impose reasonable maximum lengths on names, prompts, and log messages to reduce storage-abuse risks. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/script.sh:14
Finding
Prompt and History Files Are Created Without Explicitly Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh:14-15` **Vulnerability Type**: Insecure local file permissions **Risk Level**: Low ### Vulnerable Code ```bash mkdir -p "$DATA_DIR" touch "$PROMPTS_FILE" "$HISTORY_LOG" ``` ### Technical Analysis The script creates its data directory and plaintext files without setting a restrictive `umask` or applying explicit permissions. Effective permissions therefore depend on the caller's environment. Under a common `022` umask, a newly created directory may receive mode `0755` and files may receive mode `0644`, making saved prompts and command history readable by other local users. The history file contains subjects, original enhancement inputs, translation inputs and outputs, search terms, and complete prompts supplied to the `save` command. Although the Skill does not intentionally collect credentials, users may include confidential text in prompts. ### Attack Path 1. A user runs the Skill with a permissive umask such as `022`. 2. The script creates `$HOME/.image-prompt` and its files without overriding the inherited permissions. 3. On a multi-user system where home-directory traversal is permitted, another local user reads: ```text ~/.image-prompt/prompts.txt ~/.image-prompt/history.log ``` 4. The other user obtains stored prompt content and command-usage history. ### Impact Assessment The maximum impact is disclosure of plaintext prompts and activity history to other local accounts that can traverse the directory hierarchy. The issue does not itself provide privilege escalation, command execution, or network access. Exploitability depends on the inherited umask, existing directory permissions, parent-directory traversal permissions, and whether the host is shared by multiple users. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Set a restrictive umask before creating any persistent data: ```bash umask 077 ``` - Explicitly enforce directory and file permissions: ```bash mkdir -p -- "$DATA_DIR" chmod 700 -- "$DATA_DIR" touch -- "$PROMPTS_FILE" "$HISTORY_LOG" chmod 600 -- "$PROMPTS_FILE" "$HISTORY_LOG" ``` - Verify that `DATA_DIR` is owned by the current user and is not an unsafe symbolic link before writing. - Document that prompts and command history are stored in plaintext. - Consider making history logging optional and provide a command to clear retained history. ]]>
Vulnerability Patterns
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The core declared purpose is mostly represented: the code does generate and enhance AI image prompts. However, the implementation also includes materially additional capabilities not reflected in the description or declared permissions: persistent local storage of prompts and history, prompt library management (save/list/search), and a translation feature for Chinese descriptions. These are beyond mere supporting details for prompt optimization and should be disclosed. No evidence of network access or other dangerous behavior was found, but the undeclared local data access/persistence creates a description-behavior mismatch.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The command description says it converts a Chinese-language description into an English image prompt, which imposes a specific output language. The file does not offer language choice or explain why English-only output is required, creating a natural-language locale policy concern.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill's stated purpose is prompt generation, but it also initializes persistent storage for saved prompts and an activity history log. This broadens the data-handling surface beyond the advertised function and can expose sensitive user-provided prompt content or usage metadata if users do not expect local retention.

Ssd 3

Medium
Confidence
94% confidence
Finding
User-provided prompts are logged in plain text, and the script also logs translated inputs elsewhere, creating a durable record of potentially sensitive content. Because prompts can include proprietary concepts, internal project details, or personal information, plain-language history files increase confidentiality risk if the account or filesystem is accessed by others.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The command is described and implemented solely as converting Chinese descriptions into English prompts, and the output explicitly labels the translation as English. This is a natural-language locale policy issue because the skill forces one language direction without user opt-in or an explanation that the tool is intentionally region- or workflow-specific.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The skill states that prompts and command history are persisted under a local directory, but it does not warn users that prompts may contain sensitive or proprietary text. On shared systems or developer machines, plaintext history and saved prompts can expose confidential project details, internal ideas, or personal data to other local users, backups, or forensic review.

Missing User Warnings

Low
Confidence
96% confidence
Finding
The script creates ~/.image-prompt files automatically and stores prompts and history without an upfront warning at startup. Even though the storage is local, prompts may contain sensitive business ideas, personal data, or copyrighted material, so silent persistence creates a privacy risk.

Static analysis

No suspicious patterns detected.