Back to skill

Security audit

Make a Video

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real Pexo video-generation wrapper, but it needs review because its shell setup can expose API keys, redirect uploads or requests, and run code from a local config file.

Before installing, treat this as a hosted Pexo integration: your prompts, selected media, project metadata, generated assets, and account-credit checks may be sent to Pexo and may consume credits. Keep PEXO_BASE_URL fixed to https://pexo.ai unless you intentionally trust another endpoint, store ~/.pexo/config with restrictive permissions such as 600, and do not put anything except the expected config values in that file. Prefer a pinned installer or reviewed commit, and treat the invite code as optional promotional material unless the publisher discloses otherwise.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_common.sh:6
Finding

Executable Configuration File Enables Local Command Execution and Insecure Secret Storage

Content
View full analysis
~/.pexo/config << 'EOF' PEXO_BASE_URL="https://pexo.ai" PEXO_API_KEY="sk-" EOF ``` ### Technical Analysis The configuration file is presented as storage for two variable values, but it is loaded with Bash `source`. Consequently, every shell construct in the file is executed with the privileges of the user running the Skill. No validation limits the file to `PEXO_BASE_URL` and `PEXO_API_KEY` assignments. The `PEXO_CONFIG` environment variable can also redirect loading to another file. The implementation does not verify that the selected file is owned by the current user, is not writable by another user, or contains only permitted configuration syntax. The setup instructions also do not set a restrictive umask or apply modes `0700` and `0600` to the directory and API-key file. Depending on the existing umask, this may expose the bearer credential to other local users. ### Attack Path 1. An attacker gains write access to `~/.pexo/config`, influences `PEXO_CONFIG`, or places a malicious file at a path selected through that variable. 2. The attacker adds a shell command, command substitution, function, or other executable Bash syntax to the file. 3. The user or Agent invokes any ...[truncated 710 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_common.sh:15
Finding

Unvalidated Base URL Can Redirect Bearer Credentials and User Content to an Arbitrary Server

Content
View full analysis
&2 printf 'Set them in %s or in the environment.\n' "$_PEXO_CONFIG" >&2 return 1 fi } _pexo_auth_header() { printf 'Authorization: Bearer %s' "$PEXO_API_KEY" } ``` Authenticated requests are sent directly to the configurable destination: ```bash 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}' \ -d "$body" \ "$@" \ "${PEXO_BASE_URL}${path}" 2>"$err_file") || curl_status=$? ``` The diagnostic script likewise transmits the credential to the configured URL: ```bash 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>"$tmp_err" || echo "000") ``` ### Technical Analysis The code verifies only that `PEXO_BASE_URL` is nonempty. It does not require HTTPS, validate the hostname, reject embedded credentials, or constrain the destination to the declared Pexo service. Normal Skill operations send the bearer API key along with project names, user video requests, project identifiers, conversation content, and account-related API calls. Because the endpoint is configurable through the environment or configuration file, an ...[truncated 1315 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

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

Server-Controlled Upload URL Can Redirect User Media to an Untrusted Destination

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") ``` ### Technical Analysis Uploading a user-selected image, video, or audio file is a declared and necessary feature. However, the script trusts `uploadUrl` from the API response without validating its scheme or hostname. If the API account, backend response, proxy, or configured base endpoint is compromised, the returned value can identify an arbitrary destination. The script then sends the complete local file to that destination. A cleartext HTTP URL would also expose the media to network interception. No bearer authorization header is attached to this upload request, which limits credential exposure, but it does not protect the selected media itself. ### Attack Path 1. An attacker controls or alters the upload-credential response, directly or through a compromised/malicious configured API endpoint. 2. The response supplies an `uploadUrl` hosted by the atta ...[truncated 623 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:7
Finding

Installation Uses an Unpinned npx Package and Mutable Repository Source

Content
View full analysis
Remediation
View remediation
`. - Pin the GitHub source to a reviewed commit SHA rather than a mutable branch or repository default. - Publish checksums or signed release artifacts and verify integrity before installation. - Use npm lockfiles and integrity metadata where applicable. - Document the expected package publisher and repository commit. - Avoid automatic execution of newly fetched code when a non-executing download-and-review workflow is feasible. ]]>

T01 · Skill Instruction Hijacking

Note
Location
SKILL.md:41
Finding

First-Run Instructions Mandate Promotion of a Hard-Coded Referral Code

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear mismatch between the declared description and the actual code. The description promises end-to-end video creation from a plain-language idea, including creative generation steps such as scripting, shot selection, music, subtitles, and final editing. The code does none of that. Instead, it accepts a project ID and asset ID, calls /api/biz/projects/{project_id}/assets/{asset_id}, extracts downloadUrl, optionally downloads the referenced file with curl, stores it locally, and returns enriched asset metadata. This is an asset retrieval/download utility, not a video generation workflow. The resources accessed, inputs expected, and outputs produced are materially different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a high-level skill that takes a simple idea and produces a complete, publish-ready video. The actual code does not perform video generation orchestration or return a finished video. Instead, it is a lower-level helper for sending a message to an already existing Pexo project, with optional preview choice selection and asset-reference validation. Its primary purpose is project chat submission and acknowledgement handling, not full video creation from scratch. This is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises end-user video creation from a text idea, but the actual code does not create, edit, script, or render any video content. Its sole purpose is operational diagnostics for a shell setup. It reads local configuration, inspects installed commands, tests connectivity, and sends an authenticated request to validate API access. These are materially different capabilities and a different primary purpose from the declared video-generation behavior, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises end-to-end video generation from a user prompt. The supplied code does not accept a video idea, generate media, orchestrate production steps, or return a video. Its sole function is to call an entitlements endpoint (/api/biz/auth/entitlements), output account credit/plan information, and suggest purchasing credits when the balance is zero. That is a materially different primary purpose and an undeclared account-information capability, so this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description presents an end-to-end video creation capability from a plain-language idea, but the code chunk implements only project initialization (/api/biz/projects) with a supplied name or a default of 'Untitled'. This is a materially different and much narrower function than the declared purpose. While project creation could be a supporting step in a larger workflow, the supplied code itself does not perform the advertised video-making actions or accept a creative idea as input.

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-user capability to generate a full video from a simple prompt. The supplied code chunk does something materially different: it is an internal project-state inspection/orchestration helper (pexo-project-get.sh). It calls backend endpoints to fetch project details and history for a given project_id, strips/internalizes status fields, computes nextAction, and returns simplified message history when action is needed. There is no logic here for taking a plain-language idea, generating scripts/shots/music/subtitles, selecting models, or producing a final video. While this script may support a larger video-generation workflow, this code chunk's primary purpose is status retrieval and orchestration, which is not accurately represented by the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear mismatch between the declared description and the actual code. The description promises a full video-generation capability from a text idea, but the implementation only validates pagination arguments and fetches a list of projects for the authenticated user. It does not create videos, generate scripts, select models, add music/subtitles, perform editing, or return a final video. The primary purpose is materially different: project listing rather than 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 mismatch between the declared description and the actual code behavior. The description promises an end-to-end video creation capability from plain-language input, returning a publish-ready video. In contrast, the code only handles asset upload for an existing local file into a Pexo project. It accepts a project ID and file path, validates file type, obtains an upload credential, uploads the binary file, finalizes the asset, and returns an asset ID. This is materially different in primary purpose and capability from automated video generation. The code also supports images and audio uploads, which further indicates a lower-level asset-ingestion function rather than the described full video creation experience.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the agent to send the user's request verbatim to Pexo and to upload any provided files, but it does not include a clear user-facing warning that prompts and files are transferred to a hosted third-party service. This creates a significant privacy and data-governance risk because users may unknowingly disclose sensitive text, media, or metadata to an external provider.

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.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script executes source "$config_path" on a user-controlled config file, which causes any shell code in that file to run with the privileges of whoever launches the diagnostic script. A config file should be treated as data, not executable code; if an attacker can modify it or influence PEXO_CONFIG, this becomes arbitrary command execution.

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"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly states that all creative work and likely user-supplied prompts are handled server-side by a hosted backend, but it does not clearly warn users that their inputs may be transmitted to a third-party service. In a skill that invites free-form natural-language requests, users may include sensitive business, personal, or unreleased marketing content, making the missing disclosure a meaningful privacy and data-handling issue.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill explicitly relies on shell execution (curl, jq, file, and multiple scripts/*.sh) but does not declare any tool scope such as permissions or allowed-tools. That creates an authorization gap where the runtime may permit broader shell access than users or reviewers expect, increasing the chance of unintended command execution paths or abuse through script changes.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are very broad (make a video, create a video, I need a video for ...) and can match common conversational requests without clearly signaling that the request will be sent to a third-party hosted service. Over-broad activation can cause accidental invocation, unintended data transfer, or initiation of paid operations when the user only wanted brainstorming or local help.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
72% confidence
Finding

The workflow depends on reusing the same project_id across polling and revisions, which implies persistent session state tied to prior user inputs and assets. Without explicit user-facing disclosure and state-handling boundaries, session persistence can unintentionally retain sensitive context longer than expected or cause later prompts to act on stale data.

Content

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

md
Make a complete video from a simple idea with Pexo. Describe what you want in plain words and
  Pexo handles everything — script, shots, model selection, music, subtitles, and final editing —
  and returns a publish-ready video. Use when the user just wants to make a video: "make a video",
  "make me a video about X", "create a video", "I need a video for ...". NOT for editing a video
  they already have.
homepage: https://pexo.ai
repository: https://github.com/pexoai/pexo-skills

Session Persistence

Medium
Category
Rogue Agent
Confidence
89% confidence
Finding

These instructions create persistent local storage for an authentication token, increasing the window in which the credential can be recovered from disk, backups, or developer tooling. While persistence is often operationally convenient, storing the token long-term in an unprotected plaintext file materially raises credential exposure risk.

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
94% confidence
Finding

The setup guide instructs users to persist a live API key in a plaintext file under the home directory without warning about credential sensitivity, file permissions, or safer secret-handling options. If the file is readable by other local users, included in backups, synced, or accidentally exposed, the API key could be stolen and abused to access the Pexo account and spend credits or access generated content.

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 · 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.