Back to skill

Security audit

Startup Video

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Pexo video wrapper, but it handles API credentials and external endpoints in ways users should review before installing.

Review this before installing if you will use confidential startup plans, customer media, or paid Pexo credits. Use a restrictive config file permission such as chmod 600, do not sync or commit ~/.pexo/config, keep PEXO_BASE_URL set to https://pexo.ai, and remove cached files in ~/.pexo/tmp when outputs are sensitive.

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

Warning
Location
scripts/_common.sh:6
Finding

Executable Configuration File and Insufficient Credential File Protection

Content
View full analysis
~/.pexo/config << 'EOF' PEXO_BASE_URL="https://pexo.ai" PEXO_API_KEY="sk-" EOF ``` ### Technical Analysis The scripts load the configuration with Bash `source`, which treats the entire file as executable shell code rather than parsing it as configuration data. The optional `PEXO_CONFIG` environment variable can select another file without validating its ownership, permissions, contents, or location. Consequently, any command substitution, function definition, redirection, or arbitrary shell command placed in the selected configuration file executes whenever a Pexo script loads it. This does not independently provide an attacker with write access, but it turns compromise or unsafe delegation of the configuration file into code execution. The documented setup procedure also stores the API key without first setting `umask 077` or explicitly applying mode `600`. The resulting permissions depend on the user's ambient umask and may permit other local users to read the credential. ### Attack Path 1. An attacker gains the ability to modify `~/.pexo/config`, influence how it is provisioned, or cause a wrapper process to set `PEXO_CONFIG` to an attacker-controlled file. 2. The attacker inserts a command such as a shell invocation or command substitution into that fil ...[truncated 1157 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_common.sh:228
Finding

Bearer API Key Can Be Transmitted to an Unrestricted Configured Endpoint

Content
View full analysis
"$err_file") || curl_status=$? else http_code=$(curl -sS \ --connect-timeout "$_PEXO_CONNECT_TIMEOUT" \ --max-time "$_PEXO_REQUEST_TIMEOUT" \ -X "$method" \ -H "$(_pexo_auth_header)" \ -H "Content-Type: application/json" \ -D "$header_file" \ -o "$body_file" \ -w '%{http_code}' \ "$@" \ "${PEXO_BASE_URL}${path}" 2>"$err_file") || curl_status=$? ``` `scripts/pexo-doctor.sh:125-148`: ```bash if [[ -n "${PEXO_BASE_URL:-}" ]]; then http_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 "${PEXO_BASE_URL}" 2>/dev/null || echo "000") if [[ "$http_code" != "000" ]]; then echo "$PASS Network: can reach $PEXO_BASE_URL (HTTP $http_code)" else echo "$FAIL Network: cannot reach $PEXO_BASE_URL" echo " Check your network connection, firewall, and DNS settings." errors=$((errors + 1)) fi else echo "$WARN Network: skipped (PEXO_BASE_URL not set)" fi # 5. API key validation echo "" if [[ -n "${PEXO_BASE_URL:-}" && -n "${PEXO_API_KEY:-}" ]]; then tmp_body=$(mktemp) tmp_err=$(mktemp) http_code=$(curl -sS \ --connect-timeout 10 \ -H "Authorization: Bearer $PEXO_API_KEY" \ -H "Content-Type: application/json" \ -o "$tmp_body" \ -w '%{http_code}' \ "${PEXO_BASE_URL}/api/biz/projects?page_size=1" 2>"$t ...[truncated 1768 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/pexo-upload.sh:71
Finding

Server-Provided Upload and Download URLs Are Used Without Destination Validation

Content
View full analysis
&2; echo "$cred" >&2; exit 1; } [[ -n "$asset_id" && "$asset_id" != "null" ]] || { echo "Error: upload credential missing assetId" >&2; echo "$cred" >&2; exit 1; } [[ -n "$storage_path" && "$storage_path" != "null" ]] || { echo "Error: upload credential missing storagePath" >&2; echo "$cred" >&2; exit 1; } # Phase 2: upload file http_code=$(curl -sS -X PUT -H "Content-Type: $mime_type" \ --data-binary "@$filepath" -o /dev/null -w '%{http_code}' "$upload_url" 2>/dev/null || echo "000") ``` `scripts/pexo-asset-get.sh:42-69`: ```bash asset=$(pexo_get "/api/biz/projects/${pid}/assets/${aid}") download_url=$(echo "$asset" | jq -r '.downloadUrl // empty') if [[ -z "$download_url" ]]; then echo "$asset" | jq '. + {url:(.downloadUrl // null), localPath:null}' exit 0 fi tmp_dir=$(pexo_tmp_dir) file_name=$(echo "$asset" | jq -r '.fileName // .assetName // empty') [[ -n "$file_name" && "$file_name" != "null" ]] || file_name="${aid}.bin" safe_name=$(printf '%s' "$file_name" | sed 's#[/[:space:]]#_#g') local_path="${tmp_dir}/${aid}-${safe_name}" part_path="${local_path}.part.$$" err_file=$(mktemp) http_code="" curl_status=0 http_code=$(curl -sS -L \ --connect-timeout "$_PEXO_CONNECT_TIMEOUT" \ --max-time "$_PEXO_REQUEST_TIMEOUT" \ -o "$part_path" \ -w '%{http_code}' \ "$download_url" 2>"$err_file") || curl_status=$? ...[truncated 2150 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/_common.sh:36
Finding

Downloaded Media Is Cached Without Enforced Private Permissions or Retention Controls

Content
View full analysis
"$err_file") || curl_status=$? if [[ $curl_status -ne 0 && "${http_code:-0}" == "000" ]]; then err_text=$(cat "$err_file") rm -f "$part_path" "$err_file" _pexo_emit_error 0 "" "${err_text:-Failed to download asset from signed URL}" fi if [[ ! "${http_code:-}" =~ ^2 ]]; then err_text=$(cat "$err_file") rm -f "$part_path" rm -f "$err_file" _pexo_emit_error "${http_code:-0}" "" "${err_text:-Failed to download asset from signed URL}" fi mv -f "$part_path" "$local_path" ``` ### Technical Analysis The cache directory is created with `mkdir -p` and downloaded files are created by curl without setting a restrictive umask or explicitly applying private modes. Their permissions therefore depend on the invoking process's ambient umask. On a multi-user system, a permissive umask can result in generated media being readable by other local users. The files are moved into a persistent location under `~/.pexo/tmp` and no expiration or cleanup mechanism is provided. The `PEXO_TMP_DIR` override also permits storage ...[truncated 1035 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a user-facing startup video generation capability: script writing, shot generation, model selection, and delivery of a publish-ready video. The supplied code does none of that. It only calls an asset API endpoint for an existing project asset and, if available, downloads the file to a temp directory. This is a materially different primary purpose and exposes undeclared capability around asset retrieval/download. Therefore the description does not accurately represent the code behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a high-level skill that generates a complete startup video from a business description or website. The supplied code does not implement that workflow. Instead, it is a utility script for sending a message to an already existing Pexo project via /api/chat and receiving an async acknowledgement. While this may be a supporting component inside a broader video-generation system, the code chunk’s actual behavior is materially narrower and different from the declared primary purpose. It neither creates a project from startup information nor performs script generation, shot generation, model selection, music selection, or final video delivery.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a content-generation workflow for producing startup videos. The actual code does not generate scripts, shots, models, music, or videos, nor does it accept startup/company content as input. Instead, it functions as an environment doctor script for Pexo shell tooling, reading a config file, inspecting local dependencies, testing connectivity to the Pexo service, and validating an API key via an API request. This is a materially different primary purpose and includes undeclared operational capabilities unrelated to startup video creation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose is a creative production workflow for generating startup videos, including scripting, shots, models, and final publish-ready output. The actual code only calls an entitlements endpoint (/api/biz/auth/entitlements), returns account credit and plan information, and prints a purchase/top-up message when credits are depleted. This is a materially different primary purpose and exposes undeclared account/billing-related functionality rather than video creation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises an end-to-end startup video creation capability, including turning business information or a website into a finished publish-ready video. The supplied code only creates a blank/new Pexo project with a name and returns its project ID. While project creation could be a supporting step in a larger workflow, this chunk by itself does not implement the advertised video-generation behavior and therefore materially differs from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description presents an end-user skill that generates startup videos from a brief or website. The supplied code does not create videos, write scripts, generate shots, pick models, or return a finished video. Instead, it is a backend utility for inspecting an existing Pexo project, fetching project history, and deriving an agent-side next action. This is a materially different primary purpose and introduces undeclared capabilities around project-state retrieval and orchestration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a content-generation workflow: the user describes their startup and Pexo writes a script, generates shots, selects models, and returns a finished video. The supplied code does none of that. It only parses pagination arguments and calls an authenticated endpoint to list projects for the current user. This is a materially different primary purpose and an undeclared capability (project listing/account data retrieval) unrelated to startup video creation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises an end-to-end startup video creation workflow from high-level business inputs like a company description or website. The actual code does not perform any video creation or creative generation tasks. Instead, it implements a backend utility for uploading existing media assets to a Pexo project and finalizing them. While asset upload could be a supporting component within a broader video-production system, this code chunk by itself materially differs from the declared primary purpose and exposes capabilities/input requirements not reflected in the description.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
85% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · references/TROUBLESHOOTING.md (reported line 125)May include surrounding context.

md
- `400`: the file was rejected — possible reasons: file exceeds the size limit, file format is not supported, or the file content does not match its extension. Convert or compress the file and re-upload from scratch using `pexo-upload.sh`.
- `401`: auth failure — see Auth and Proxy Errors above.
- `404`: the file record was not found. The upload session may have been cleaned up. Re-upload from scratch using `pexo-upload.sh`.
- `412`: the upload session has already expired or been completed. Re-upload from scratch using `pexo-upload.sh`.
- `500`: an unexpected server error occurred. Retry in a moment; if the problem persists, contact support at pexo.ai.

Context Leakage

High
Category
Data Exfiltration
Confidence
85% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · references/TROUBLESHOOTING.md (reported line 126)May include surrounding context.

md
- `400`: the file was rejected — possible reasons: file exceeds the size limit, file format is not supported, or the file content does not match its extension. Convert or compress the file and re-upload from scratch using `pexo-upload.sh`.
- `401`: auth failure — see Auth and Proxy Errors above.
- `404`: the file record was not found. The upload session may have been cleaned up. Re-upload from scratch using `pexo-upload.sh`.
- `412`: the upload session has already expired or been completed. Re-upload from scratch using `pexo-upload.sh`.
- `500`: an unexpected server error occurred. Retry in a moment; if the problem persists, contact support at pexo.ai.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly instructs users to describe their company or paste their site, while also stating that creative work happens on a hosted backend, but it does not clearly warn that user-provided business content will be transmitted to a third-party service. This creates a real privacy and data-handling risk because users may submit confidential startup plans, internal messaging, or unpublished product details without informed consent.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 15)May include surrounding context.

Configure

Create ~/.pexo/config:

text
PEXO_BASE_URL="https://pexo.ai"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares shell runtime requirements and instructs execution of multiple local scripts, but it does not define an explicit tool scope such as permissions or allowed-tools. That increases the attack surface because a host agent may permit broader shell usage than is necessary, making misuse or unintended command execution harder to constrain or audit.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly instructs sending the user's website or brief verbatim to a hosted backend, but it provides no clear privacy notice or consent checkpoint before transmitting potentially sensitive business information. Users may unknowingly disclose unreleased product plans, internal messaging, or personal data to a third party.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill creates and reuses persistent server-side project context, instructs the agent to keep polling, and sends subsequent revisions into the same project. Persistent session state can expose prior user content across turns, increase accidental data retention, and make it easier to continue operations on a stale or unintended project if identifiers are mixed up.

Content

Scanner excerpt · SKILL.md (reported line 27)May include surrounding context.

md
website — to the hosted Pexo agent and deliver the result; Pexo writes the script, generates the
shots, and assembles a polished startup video with music.

## Your role: relay, don't create

Create a project, send the user's request **verbatim**, poll, deliver. Pexo's backend handles
all creative work — scriptwriting, model choice, prompts, music. Adding your own direction

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The workflow directs the agent to upload any user files to an external service without warning the user that their local media will leave the current environment. This creates a privacy and data-governance risk, especially if users attach proprietary assets, customer media, or regulated content.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The instructions establish persistent local session-like authentication material by saving the API key to ~/.pexo/config, enabling future scripts to reuse it automatically. Persistent credential storage is not inherently malicious, but without safeguards it broadens the window for theft by local users, malware, backups, or accidental disclosure.

Content

Scanner excerpt · references/SETUP-CHECKLIST.md (reported line 7)May include surrounding context.

Quick Start

1. Create config file

bash
mkdir -p ~/.pexo

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The setup instructions direct users to store a live API key in a plaintext file under their home directory without any warning about file permissions, secret handling, shell history, or multi-user system exposure. While this is a common convenience pattern, it increases the risk of credential disclosure through lax permissions, backups, dotfile syncing, or local compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The diagnostics step states that the tool validates the API key by contacting Pexo servers, but it does not clearly warn users that their credential will be transmitted over the network as part of verification. This omission reduces informed consent and may be problematic in restricted or sensitive environments, though the destination is the expected service over HTTPS.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
79% confidence
Finding

The documentation confirms that pexo-asset-get.sh persists downloaded assets to a local temp directory and exposes a localPath. In a startup-video workflow, these assets may contain unpublished marketing media, product visuals, or other sensitive business material; storing them on disk without a clear warning about retention, permissions, and cleanup increases the risk of unintended local disclosure on shared or insecure systems.

Content

Scanner excerpt · references/TROUBLESHOOTING.md (reported line 181)May include surrounding context.

md
- `403`: the download link has expired. Re-run `pexo-asset-get.sh` to get a fresh link.
- `000`: network request failed before receiving a response. Check network connectivity and retry.
- local filesystem write failure: the temp directory (`~/.pexo/tmp/`) is not writable or the disk is full. Free up space or set `PEXO_TMP_DIR` to a writable path.

Notes:

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/_common.sh (reported line 228)May include surrounding context.

sh
err_file=$(mktemp)

  if [[ -n "$body" ]]; then
    http_code=$(curl -sS \
      --connect-timeout "$_PEXO_CONNECT_TIMEOUT" \
      --max-time "$_PEXO_REQUEST_TIMEOUT" \
      -X "$method" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/_common.sh (reported line 241)May include surrounding context.

sh
err_file=$(mktemp)

  if [[ -n "$body" ]]; then
    http_code=$(curl -sS \
      --connect-timeout "$_PEXO_CONNECT_TIMEOUT" \
      --max-time "$_PEXO_REQUEST_TIMEOUT" \
      -X "$method" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/_common.sh (reported line 335)May include surrounding context.

sh
set +o pipefail
  if [[ -n "$body" ]]; then
    curl -sS -N \
      --connect-timeout "$_PEXO_CONNECT_TIMEOUT" \
      --max-time "$timeout" \
      -X POST \

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/pexo-doctor.sh (reported line 79)May include surrounding context.

sh
source "$config_path"
else
  echo "$FAIL Config file not found: $config_path"
  echo "  Create it with:"
  echo '  mkdir -p ~/.pexo && cat > ~/.pexo/config << EOF'
  echo '  PEXO_BASE_URL="https://pexo.ai"'
  echo '  PEXO_API_KEY="sk-<your-api-key>"'

Static analysis

No suspicious patterns detected.