Back to skill

Security audit

ofox-image-core

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Ofox image API client, but it needs Review because custom endpoint and advanced JSON options can undermine key handling, billing approval, and safety controls.

Review before installing or using for paid generations. Use it only if you trust Ofox and the scenario skills that call this library, avoid sensitive prompts, leave OFOX_API_BASE_URL unset unless you intentionally control the endpoint, do not source unreviewed dotenv files as shell code, and treat --extra-json as privileged because it can change the effective request. Safety refusals should be treated as a boundary, not as a reason to search for another model that will accept the same prompt.

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
references/ofox-image.sh:146
Finding
API Key Disclosure Through an Unrestricted Endpoint Override<![CDATA[ ## Vulnerability Details **File Location**: `references/ofox-image.sh:146` and `references/ofox-image.sh:1555-1563` **Vulnerability Type**: Credential exfiltration through an attacker-controlled API endpoint **Risk Level**: High ### Vulnerable Code ```bash API_BASE="${OFOX_API_BASE_URL:-https://api.ofox.ai/v1}" ``` ```bash local tmp_body http_code curl_rc body tmp_body=$(mktemp) http_code=$(curl -sS -o "$tmp_body" -w '%{http_code}' \ --connect-timeout "$CONNECT_TIMEOUT" --max-time "$GENERATE_MAX_TIME" \ -X POST "$API_BASE/images/generations" \ -H "Authorization: Bearer $OFOX_API_KEY" \ -H "Content-Type: application/json" \ -d "$payload") ``` Related instructions in `SKILL.md:38-42` recommend sourcing an authorized dotenv file and acknowledge that `OFOX_API_BASE_URL` can silently redirect API calls: ```markdown Locate it (`.env` at the repo root is the usual spot), then `set -a; . <path>; set +a` in the shell you'll call the script from. Sourcing a dotenv pulls in *every* variable in the file, not just the key — `OFOX_API_BASE_URL` is one this script reads, and it silently redirects every API call — so read the file before you load it. ``` ### Technical Analysis The destination of the authenticated image-generation request is taken directly from the `OFOX_API_BASE_URL` environment variable. The script does not validate that the resulting URL: - Uses HTTPS. - Belongs to the trusted `api.ofox.ai` origin. - Contains no embedded user information. - Is an explicitly authorized development endpoint. The same request includes `Authorization: Bearer $OFOX_API_KEY`. Consequently, any process or sourced environment file that controls `OFOX_API_BASE_URL` controls where the production API credential is transmitted. This is especially risky because the Skill instructs the Agent to source dotenv files with: ```bash set -a; . /path/to/.env; set +a ``` That operation imports every variable and executes the file as shell code rather than reading ...[truncated 2016 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Pin production requests to the trusted Ofox origin.** For normal authenticated operation, use a constant endpoint: ```bash readonly API_BASE="https://api.ofox.ai/v1" ``` 2. **If endpoint overrides are required for testing, make them explicitly unsafe and opt-in.** Require a separate switch such as `OFOX_ALLOW_CUSTOM_API_BASE=1`, and reject overrides by default. 3. **Never forward the production key to a custom origin.** Require a separate development credential variable when a custom endpoint is enabled: ```bash if [ -n "${OFOX_API_BASE_URL:-}" ]; then [ "${OFOX_ALLOW_CUSTOM_API_BASE:-}" = "1" ] || exit 2 API_KEY="${OFOX_CUSTOM_API_KEY:-}" else API_BASE="https://api.ofox.ai/v1" API_KEY="${OFOX_API_KEY:-}" fi ``` 4. **Validate URL properties before transmission.** At minimum, require HTTPS, reject URL user information, and compare the parsed hostname and port against an allowlist. 5. **Avoid sourcing dotenv files as shell scripts.** Read only the required variable using a parser that does not execute file content. Do not import unrelated variables into the generation process. 6. **Use a reduced environment when invoking the client.** Explicitly unset endpoint override variables unless the user separately approved a custom endpoint. 7. **Add regression tests** proving that an unapproved custom origin cannot receive `OFOX_API_KEY` and that plaintext HTTP endpoints are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/ofox-image.sh:1464
Finding
Last-Write-Wins Extra JSON Bypasses Validation and Cost Approval<![CDATA[ ## Vulnerability Details **File Location**: `references/ofox-image.sh:1464-1520` **Vulnerability Type**: Validated request-field override and billing approval bypass **Risk Level**: Medium ### Vulnerable Code ```bash if [ -n "$extra_json" ]; then if ! printf '%s' "$extra_json" | jq -e . >/dev/null 2>&1; then echo "ERROR: --extra-json is not valid JSON." >&2 return 1 fi if printf '%s' "$extra_json" | jq -e 'has("input_images")' >/dev/null 2>&1; then echo "ERROR: --extra-json sets 'input_images' — image-to-image is out of scope for ofox-image-core v1 (text-to-image only). See SKILL.md." >&2 return 1 fi if printf '%s' "$extra_json" | jq -e '.stream == true' >/dev/null 2>&1; then echo "ERROR: --extra-json sets 'stream: true' — this script only parses a plain JSON response body, not a streamed one. Omit stream or leave it false." >&2 return 1 fi if [ "$model" = "$NO_N_MODEL" ] && printf '%s' "$extra_json" | jq -e 'has("n")' >/dev/null 2>&1; then echo "ERROR: --extra-json sets 'n' while --model is $NO_N_MODEL, which does not support n at all. Remove it from --extra-json." >&2 return 1 fi fi ``` ```bash local payload='{}' payload=$(printf '%s' "$payload" | jq --arg v "$model" '.model=$v') payload=$(printf '%s' "$payload" | jq --arg v "$prompt" '.prompt=$v') payload=$(printf '%s' "$payload" | jq --arg v "$quality" '.quality=$v') [ -n "$size" ] && payload=$(printf '%s' "$payload" | jq --arg v "$size" '.size=$v') [ -n "$n" ] && payload=$(printf '%s' "$payload" | jq --argjson v "$n" '.n=$v') [ -n "$output_format" ] && payload=$(printf '%s' "$payload" | jq --arg v "$output_format" '.output_format=$v') [ -n "$background" ] && payload=$(printf '%s' "$payload" | jq --arg v "$background" '.background=$v') if [ -n "$extra_json" ]; then payload=$(printf '%s' "$payload" | jq --argjson extra "$extra_json" '. * $extra') fi print_estimate "$model" "${n:-1}" "$quality" "$size" ``` The behavior is explicitly described ...[truncated 3110 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Reserve all core request keys.** Reject `--extra-json` if it contains any field already represented by a dedicated option: ```bash if printf '%s' "$extra_json" | jq -e ' has("model") or has("prompt") or has("quality") or has("size") or has("n") or has("output_format") or has("background") or has("input_images") or has("stream") ' >/dev/null; then echo "ERROR: --extra-json may only contain approved extension fields." >&2 return 1 fi ``` 2. **Prefer an allowlist over a blocklist.** If the current legitimate use is only `extra_body.provider.type`, validate that exact nested structure and reject all other keys. 3. **Validate the final payload.** If overrides must remain supported, perform the merge before validation and read every effective field back from the merged payload. 4. **Calculate estimates from the final payload.** Extract the effective model, count, quality, and size from `payload`, then pass those values to `print_estimate`. 5. **Resolve model availability and compatibility after the merge.** Model-specific checks must apply to the model that will actually be transmitted. 6. **Display the effective request parameters** in dry-run and approval output so callers can detect discrepancies. 7. **Add regression tests** for overrides of `model`, `prompt`, `quality`, `size`, `n`, `output_format`, and `background`. Tests should confirm either rejection or consistent final-payload validation and pricing. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Ssd 4

High
Confidence
99% confidence
Finding
This documentation gives an explicit operational playbook for defeating or working around image-model safety refusals: rerunning blocked prompts, bisecting prompts to isolate trigger terms, rewriting only the blocked clause, and switching to a more permissive model to preserve content. Even though framed as troubleshooting, it materially enables policy-evasion and harmful-content generation by helping callers retain disallowed content while avoiding filters.

Ssd 1

High
Confidence
99% confidence
Finding
The file directly recommends re-running a refused prompt on an alternative model as a way past safety refusals. That is an explicit cross-model safety-bypass strategy: if one provider blocks content, try another with a weaker policy, increasing the likelihood of generating content that was intentionally refused.

External Transmission

Medium
Category
Data Exfiltration
Content
# ofox-image-core: Ofox image API execution layer

Wraps the Ofox image generation API (`https://api.ofox.ai/v1/images/generations`)
behind one script: validate, request, decode, save, report real token usage.
Unlike `ofox-video-core`, this API is **synchronous** — one request either
returns the finished image(s) in the response body or fails outright. There
Confidence
92% confidence
Finding
The skill is explicitly designed to transmit user-supplied prompts and an API key to an external third-party service at api.ofox.ai. Any external transmission of user content can expose sensitive data if prompts contain secrets, proprietary material, or regulated information, and the skill also permits redirection via an environment-controlled base URL according to the documentation.

External Transmission

Medium
Category
Data Exfiltration
Content
echo "Requesting image generation from Ofox (model=$model)..." >&2
  local tmp_body http_code curl_rc body
  tmp_body=$(mktemp)
  http_code=$(curl -sS -o "$tmp_body" -w '%{http_code}' \
    --connect-timeout "$CONNECT_TIMEOUT" --max-time "$GENERATE_MAX_TIME" \
    -X POST "$API_BASE/images/generations" \
    -H "Authorization: Bearer $OFOX_API_KEY" \
Confidence
84% confidence
Finding
The script transmits user-supplied prompt data and the bearer API key to a remote service via curl. This is expected for an API client, but it is still a real data egress and secret-handling boundary; additionally, the destination can be overridden via OFOX_API_BASE_URL, which increases the risk of credential exfiltration to an attacker-controlled endpoint if the environment is poisoned.

External Transmission

Medium
Category
Data Exfiltration
Content
set -u

API_BASE="${OFOX_API_BASE_URL:-https://api.ofox.ai/v1}"
GET_KEY_URL="https://app.ofox.ai"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
Confidence
79% confidence
Finding
The configurable API base URL creates an external transmission sink that can redirect both request contents and the OFOX_API_KEY to an arbitrary host. In a hostile execution environment, this turns a normal API client into a credential exfiltration primitive.

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.potential_exfiltration

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
CHANGELOG.md:14

Shell script base64-encodes a local file and sends it over the network.

Critical
Code
suspicious.potential_exfiltration
Location
references/ofox-image.sh:302