Back to skill

Security audit

Pexo Video Agent

Security checks for vulnerabilities and agentic risk

Overview

The skill broadly matches its video-generation purpose, but it needs review because it relays remote service text and links and sends media to server-supplied URLs without enough validation.

Review before installing if your media files may be sensitive or if you run agents on a network with private internal services. Use it only for files you intentionally choose, keep the API key scoped and removable, and treat returned messages, billing links, and signed asset URLs as external Pexo-provided content rather than trusted local instructions.

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

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:105
Finding

Untrusted Backend Content Is Required to Be Relayed Verbatim

Content
View full analysis
"{user's exact answer}" Go back to Step 5. ``` ```markdown Step A. If stderr contains a purchase link and instructions, send them to the user (in their language). Step B. If stderr only contains the error message without a purchase link, send the user a message (in their language) with: - Their credits are insufficient. - To add credits: visit https://pexo.ai/home?billing=credits and complete the purchase flow. ``` ### Technical Analysis The Skill text uses priority-asserting language and redefines the Agent as a passive “delivery worker.” More importantly, it requires externally supplied Pexo messages, error instructions, and purchase links to be relayed in full. Content returned by a remote service is outside the local trust boundary and must be treated as untrusted data. Requiring verbatim relay prevents the Agent from independently assessing whether a response contains prompt injection, misleading billing instructions, unsafe links, requests for secrets, or instructions unrelated to video production. The same-langu ...[truncated 1408 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pexo-upload.sh:70
Finding

Server-Provided Upload URL Is Used Without Scheme or 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: PUT raw bytes to presigned URL 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") [[ "$http_code" =~ ^2 ]] || { echo "Error: upload failed with HTTP $http_code" >&2; exit 1; } ``` ### Technical Analysis The authenticated request used to obtain the upload credential is locked to `https://pexo.ai`, but the returned `uploadUrl` crosses a second trust boundary. The script only checks whether this value is nonempty. It does not require HTTPS, verify the hostname or port, reject credential-bearing URLs, or prevent loopback, link-local, and private-network destinations. The script then sends the complete contents of the selected local file to that URL using an HTTP PUT request. Presigned object-storage URLs are necessary for the declared upload workflow, but destination validation remains necessary because the API response itself may be compromised or malformed. The Pexo API key is not attached to this secondary upload request. The expos ...[truncated 1254 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pexo-asset-get.sh:84
Finding

Unvalidated Download URL and Redirect Chain Permit Arbitrary Network Requests

Content
View full analysis
"$err_file") || curl_status=$? ``` ### Technical Analysis The download URL is supplied by the remote API and passed directly to `curl`. The `-L` option follows redirects, but neither the initial URL nor redirect targets are validated. Consequently, a compromised or malformed backend response can make the client issue GET requests to arbitrary destinations, including HTTP endpoints, loopback services, private-network systems, or cloud metadata endpoints. Curl may also switch protocols unless restricted explicitly. The response is stored locally rather than returned to Pexo, so this is primarily a blind SSRF and arbitrary-download primitive. Subsequent Agent beh ...[truncated 1240 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pexo-asset-get.sh:91
Finding

Unvalidated Asset Identifier Is Embedded in the Local Download Path

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This variant includes a materially security-relevant mismatch: the skill claims authenticated requests are locked to https://pexo.ai, yet the workflow explicitly instructs use of outbound presigned asset URLs for upload/download. If users or operators rely on the stronger claim, they may underestimate external data transfer paths and fail to review or constrain non-pexo.ai endpoints handling user assets.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This variant includes a materially security-relevant mismatch: the skill claims authenticated requests are locked to https://pexo.ai, yet the workflow explicitly instructs use of outbound presigned asset URLs for upload/download. If users or operators rely on the stronger claim, they may underestimate external data transfer paths and fail to review or constrain non-pexo.ai endpoints handling user assets.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This variant includes a materially security-relevant mismatch: the skill claims authenticated requests are locked to https://pexo.ai, yet the workflow explicitly instructs use of outbound presigned asset URLs for upload/download. If users or operators rely on the stronger claim, they may underestimate external data transfer paths and fail to review or constrain non-pexo.ai endpoints handling user assets.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This variant includes a materially security-relevant mismatch: the skill claims authenticated requests are locked to https://pexo.ai, yet the workflow explicitly instructs use of outbound presigned asset URLs for upload/download. If users or operators rely on the stronger claim, they may underestimate external data transfer paths and fail to review or constrain non-pexo.ai endpoints handling user assets.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This variant includes a materially security-relevant mismatch: the skill claims authenticated requests are locked to https://pexo.ai, yet the workflow explicitly instructs use of outbound presigned asset URLs for upload/download. If users or operators rely on the stronger claim, they may underestimate external data transfer paths and fail to review or constrain non-pexo.ai endpoints handling user assets.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Resolve `SKILL_ROOT` to the directory containing this `SKILL.md`. Script names

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 121)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 122)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.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly requires shell and outbound HTTPS access but does not declare a restrictive tool scope such as allowed-tools or permissions. In an agent environment, this increases the attack surface because broad shell/network capability can be abused by prompt injection, implementation drift, or future script changes to perform unintended actions without policy-level containment.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The setup flow persists the PEXO_API_KEY in ~/.pexo/config, creating session-spanning credential storage on disk. Even with umask 077 and chmod 600, persistent plaintext secrets increase the blast radius of local compromise, accidental backup leakage, or unintended reuse across projects/sessions in agent environments.

Content

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

bash
umask 077
mkdir -p ~/.pexo
read -rsp "Pexo API key: " pexo_api_key
printf '\n'
{

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The markdown explicitly states that replies MUST be in the same language as the user and calls this non-negotiable. This is a natural-language locale policy constraint that removes user choice and is not framed as optional or justified as a region-specific requirement.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The setup instructions persist the Pexo API key in ~/.pexo/config, creating a long-lived local secret on disk. Even with umask 077 and chmod 600, the key remains exposed to compromise from account takeover, local malware, backups, shell access by the same user, or accidental inclusion in copied home-directory data; in this skill context, that could enable unauthorized authenticated API use and billing-impacting actions.

Content

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

Quick Start

1. Create config file

bash
umask 077

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

printf '%s=%s\n' PEXO_API_KEY "$pexo_api_key" } > ~/.pexo/config unset pexo_api_key chmod 600 ~/.pexo/config

text

Get your API key at: https://pexo.ai

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

printf '%s=%s\n' PEXO_API_KEY "$pexo_api_key" } > ~/.pexo/config unset pexo_api_key chmod 600 ~/.pexo/config

text

Get your API key at: https://pexo.ai

Session Persistence

Medium
Category
Rogue Agent
Confidence
73% confidence
Finding

The documentation confirms that downloaded assets are written to a persistent local temp directory under the user's home path and may be redirected via an environment variable. In a skill that handles generated media and local file access, this increases risk of residual sensitive assets remaining on disk, being exposed to other local processes/users, or being redirected to an unsafe location if PEXO_TMP_DIR is manipulated.

Content

Scanner excerpt · references/TROUBLESHOOTING.md (reported line 174)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:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

sh
pexo_tmp_dir() {
  local tmp_dir="${PEXO_TMP_DIR:-$HOME/.pexo/tmp}"
  mkdir -p "$tmp_dir"
  chmod 700 "$tmp_dir"
  printf '%s\n' "$tmp_dir"
}

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 321)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 334)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 397)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 \

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 408)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 \

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

sh
echo "$WARN Could not determine config file permissions"
  elif [[ "${config_mode: -2}" != "00" ]]; then
    echo "$FAIL Config file is accessible by group or other users (mode $config_mode)"
    echo "  Fix with: chmod 600 $config_path"
    errors=$((errors + 1))
  else
    echo "$PASS Config file permissions are owner-only (mode $config_mode)"

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/pexo-upload.sh (reported line 83)May include surrounding context.

sh
[[ -n "$storage_path" && "$storage_path" != "null" ]] || { echo "Error: upload credential missing storagePath" >&2; echo "$cred" >&2; exit 1; }

# Phase 2: PUT raw bytes to presigned URL
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")

[[ "$http_code" =~ ^2 ]] || { echo "Error: upload failed with HTTP $http_code" >&2; exit 1; }

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script performs a network transfer of the specified local file to a remote presigned URL using curl, but there is no confirmation prompt or explicit user-facing warning at the point of transmission. The usage text describes upload steps, but the execution path itself provides no visible disclosure when data leaves the local system.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.