Back to skill

Security audit

Youtube → Pocket Casts

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform its stated upload workflow, but it asks users to handle long-lived account credentials and runs unpinned external code with access to those credentials.

Install only if you are comfortable storing a Pocket Casts refresh token and YouTube cookies locally and letting the script's runtime tools access them. Prefer reviewing or pinning the external tools first, avoid running it with elevated privileges, keep the credentials directory locked down, rotate/revoke the token and cookies if logs or files are exposed, and use it only for media you have rights to download and upload.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:32
Finding
Unverified Remote Installer Executed Directly by the Shell<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 32-35 **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```bash ### Recommended - **deno** - JavaScript runtime for yt-dlp challenges: ```bash curl -fsSL https://deno.land/install.sh | sh ``` ``` ### Technical Analysis The installation instructions pipe a mutable network response directly into `sh`. The downloaded installer is neither pinned to a specific release nor validated with a cryptographic signature or checksum. The user also has no opportunity to inspect the retrieved script before execution. Although `deno.land` is an official Deno domain and Deno is described as an optional dependency, reliance on a legitimate domain does not eliminate the risk. A compromise of the hosting infrastructure, installer publication process, DNS resolution, certificate trust chain, or upstream account could change the effective payload after the Skill has been reviewed. This behavior is not required for the Skill's core upload operation. Deno is only recommended for some `yt-dlp` challenges, and it can be installed through a verified, version-pinned package or artifact instead. ### Attack Path 1. An attacker compromises or redirects the remote installer endpoint or its publication pipeline. 2. The response at `https://deno.land/install.sh` is modified to contain attacker-controlled shell commands. 3. A user follows the Skill's documented prerequisite instructions. 4. `curl` retrieves the modified response and passes it directly to `sh`. 5. The payload runs with all privileges available to the user who invoked the command. 6. The payload can read user-accessible credentials, modify files, install persistence, or execute additional programs. ### Impact Assessment Successful exploitation provides arbitrary command execution under the invoking user's account. This can expose the Pocket Casts refresh token, YouTube session cookies, SSH k ...[truncated 249 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `curl | sh` installation command. - Pin Deno to a reviewed release and download the corresponding official artifact. - Verify the artifact using a published cryptographic signature or a checksum obtained through an independently authenticated channel. - Save the installer locally and require inspection before execution if a script-based installation remains necessary. - Prefer an operating-system package manager or another repository with package signature verification. - Clearly state that Deno is optional and avoid installing it unless the selected video actually requires it. - Run optional dependencies in a restricted environment without access to the Pocket Casts token or browser cookies where practical. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/upload.sh:66
Finding
Unpinned Third-Party Package Is Downloaded and Executed at Runtime<![CDATA[ ## Vulnerability Details **File Locations**: `SKILL.md`, line 25; `scripts/upload.sh`, lines 66 and 84 **Vulnerability Type**: Insecure dependency execution **Risk Level**: High ### Vulnerable Code From `SKILL.md`: ```markdown - **yt-dlp** - YouTube downloader (via uv: `uvx yt-dlp`) ``` From `scripts/upload.sh`: ```bash VIDEO_INFO=$(uvx yt-dlp "${YTDLP_ARGS[@]}" --print "%(title)s|||%(id)s" "$VIDEO_URL" 2>/dev/null) || { warn "Failed to get video info. YouTube may require cookies." warn "Export cookies from your browser using a browser extension like 'Get cookies.txt LOCALLY'" warn "Save the file as: $COOKIES_FILE" err "Download failed" } ``` ```bash uvx yt-dlp "${YTDLP_ARGS[@]}" "$VIDEO_URL" --remux-video mp4 -o "$OUTPUT_FILE" --no-playlist || err "Failed to download video" ``` ### Technical Analysis The script invokes `yt-dlp` through `uvx` without specifying a reviewed version or validating package artifacts. `uvx` can resolve, retrieve, and execute Python package code at runtime. Consequently, the code that runs may change between invocations even when the Skill itself has not changed. The package executes in the user's security context. When YouTube cookies are configured, the script explicitly passes the sensitive cookie file to the package through `--cookies`. A malicious or compromised dependency release could therefore read and exfiltrate authenticated YouTube session cookies. It could also inspect the default credentials hierarchy and access the Pocket Casts refresh token because no process isolation prevents it from reading other user-accessible files. There is no evidence that the current `yt-dlp` package is malicious. The vulnerability is the absence of version and artifact integrity controls around runtime dependency execution. ### Attack Path 1. An attacker compromises the upstream package account, package index, publishing pipeline, or dependency resolution path. 2. A malicious release is published under the ...[truncated 1003 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `yt-dlp` to a specifically reviewed version rather than invoking the latest resolvable package. - Maintain a lockfile with cryptographic hashes for the package and its transitive dependencies. - Install dependencies in a dedicated virtual environment during an explicit setup step rather than resolving executable code during every upload. - Verify downloaded package artifacts against trusted hashes or signatures. - Treat dependency upgrades as reviewed changes and test them before deployment. - Isolate the downloader process where possible, granting it access only to the required cookie file and temporary output directory. - Keep the Pocket Casts refresh token outside the downloader's accessible environment or provide it only to the separate upload stage. - Document the exact supported package version in `SKILL.md`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/upload.sh:8
Finding
Predictable Shared Temporary Paths Permit Symlink and File-Clobbering Attacks<![CDATA[ ## Vulnerability Details **File Location**: `scripts/upload.sh`, lines 8, 44-45, 82, 125, and 134-135 **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```bash TEMP_DIR="/tmp/pocket-casts-upload" ``` ```bash # Create temp dir mkdir -p "$TEMP_DIR" cd "$TEMP_DIR" ``` ```bash OUTPUT_FILE="$TEMP_DIR/${VIDEO_ID}.mp4" ``` ```bash HTTP_CODE=$(curl -s -w "%{http_code}" -o /tmp/pc-upload-response.txt \ -X PUT \ -H "Content-Type: video/mp4" \ -T "$OUTPUT_FILE" \ "$UPLOAD_URL") ``` ```bash rm -f "$OUTPUT_FILE" rm -f /tmp/pc-upload-response.txt ``` ### Technical Analysis The script uses fixed paths under the globally shared `/tmp` directory. It does not create a unique private directory, enforce restrictive permissions, validate path ownership, or reject symbolic links. A local attacker who can write to `/tmp` may pre-create `/tmp/pocket-casts-upload`, a predictable output filename when the video ID is known, or `/tmp/pc-upload-response.txt`. These paths can be symbolic links to files writable by the victim. Subsequent operations by `yt-dlp`, `curl`, or `rm` may then write through or operate on attacker-selected paths. The fixed media directory can also expose downloaded content to other local users if inherited permissions are permissive. Concurrent script executions share the same directory and response file, creating collision and integrity risks even without a malicious local actor. ### Attack Path 1. A local attacker observes that the Skill uses fixed paths in `/tmp`. 2. The attacker creates `/tmp/pc-upload-response.txt` as a symbolic link to a victim-owned file that the invoking user can modify. Alternatively, the attacker prepares the shared media directory or a predictable video output path. 3. The victim runs the upload script. 4. `curl -o /tmp/pc-upload-response.txt` follows the prepared link and truncates or overwrites the target with the HTTP response. 5. For a prepared media path, `yt ...[truncated 737 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create a unique private temporary directory: ```bash umask 077 TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/pocket-casts-upload.XXXXXX")" ``` - Store the downloaded media and HTTP response file only inside that private directory. - Register reliable cleanup immediately after directory creation: ```bash trap 'rm -rf -- "$TEMP_DIR"' EXIT ``` - Avoid fixed filenames directly under `/tmp`. - Validate that the temporary directory is owned by the current user and is not a symbolic link if compatibility prevents use of `mktemp`. - Quote all temporary paths and use `--` before path operands for commands that support it. - Prevent concurrent executions from sharing state. - Apply restrictive permissions to temporary media because downloaded content may be private. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill clearly instructs users to run a shell script and install command-line tools, but it does not declare any corresponding permissions. Undeclared shell capability weakens transparency and review controls, making it easier for a skill to execute local commands or process files without users understanding the operational risk.

Credential Access

High
Category
Privilege Escalation
Content
## How It Works

1. Downloads video via `yt-dlp --remux-video mp4`
2. Refreshes Pocket Casts access token using stored refresh token
3. Requests presigned upload URL from Pocket Casts API
4. PUTs file to S3 via presigned URL
5. Deletes local video file
Confidence
80% confidence
Finding
The skill is designed to access and use sensitive authentication material, including a Pocket Casts refresh token and YouTube cookies, to obtain access tokens and perform uploads. Even though this appears functional rather than malicious, handling long-lived tokens and browser cookies increases the blast radius if the script, logs, or credential storage are compromised.

Credential Access

High
Category
Privilege Escalation
Content
--data-raw "{\"grantType\":\"refresh_token\",\"refreshToken\":\"$REFRESH_TOKEN\"}")

ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.accessToken')
[[ -n "$ACCESS_TOKEN" && "$ACCESS_TOKEN" != "null" ]] || err "Failed to get access token: $TOKEN_RESPONSE"

log "Got access token"
Confidence
88% confidence
Finding
If token refresh fails, the script includes the full TOKEN_RESPONSE in the error message. API error bodies can contain sensitive authentication material, account details, or debugging data, so echoing them to stderr may leak secrets into terminal history, logs, agent transcripts, or centralized monitoring systems.

Static analysis

No suspicious patterns detected.