Back to skill

Security audit

YouTube Full Channel Transcripts

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but its shell script has unsafe input and temporary-file handling that could damage local files.

Install only if you are comfortable running a local shell wrapper around yt-dlp. Prefer JSON output, use a dedicated output directory, avoid untrusted parameter values, and review or patch the script before using it in shared systems or automated workflows.

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

Error
Location
bin/extract.sh:43
Finding

Unvalidated Output Format Permits Arbitrary File Truncation

Content
View full analysis
"$OUTPUT_FILE" # clear ``` ### Technical Analysis The documented values for `output_format` are `json` and `csv`, but the script does not enforce this allowlist. Instead, it incorporates the caller-controlled value directly into a filesystem path and immediately truncates the resulting file through shell redirection. The later `case "$OUTPUT_FORMAT"` statement does not protect this operation because truncation occurs before the format is checked. Path separators and parent-directory components are therefore processed by the operating system. Because the fixed `transcripts.` prefix precedes the attacker-controlled value, straightforward traversal may require an attacker-accessible directory matching the resulting prefix component. For example, an attacker who can select `output_dir` and prepare directories beneath it can create the required prefix directory and use `../` components in `output_format` to resolve the constructed path outside the intended export directory. ### Attack Path 1. The attacker identifies a file writable by the account running the Skill. 2. The attacker creates an accessible output directory and any prefix directory required by the fixed `transcripts.` path component. 3. The attacker invokes the Skill with a crafted `output_format` containing path separators and parent-directory traversal components. 4. The assignment constructs a path outside the intended export location. 5. The command `> "$OUTPUT_FILE"` follows the resolved path and truncates the target before the script validates whether the requested format is supported. ### Impact Assessment Successful exploitation can truncat ...[truncated 358 chars]
Remediation
View remediation
&2 exit 2 ;; esac ``` Additionally: 1. Resolve `OUTPUT_DIR` to a canonical path. 2. Construct the destination using a fixed filename selected by the allowlist rather than concatenating raw input. 3. Resolve the final output path and verify that it remains beneath the approved output directory. 4. Refuse symlink destinations where appropriate. 5. Create output files with restrictive permissions, such as through `umask 077`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
bin/extract.sh:21
Finding

yt-dlp Option Injection Through Unvalidated max_videos Input

Content
View full analysis
/tmp/playlist.json || { echo "Error: Failed to fetch playlist/channel info" exit 1 } ``` ### Technical Analysis `max_videos` is documented as an integer but is accepted without validation. The script places it into the scalar variable `PLAYLIST_OPTS`, which is then expanded without quotation: ```bash $PLAYLIST_OPTS ``` Unquoted expansion causes Bash word splitting. A value containing whitespace can consequently generate multiple command-line arguments rather than one numeric argument to `--playlist-end`. This is not direct shell metacharacter injection because Bash does not automatically reparse metacharacters stored in the variable. It is nevertheless option injection into `yt-dlp`. An attacker can append additional options supported by the installed `yt-dlp` version. Since `yt-dlp` supports options that affect filesystem output and post-processing behavior, the injected arguments can cross a command-execution or arbitrary-file-write boundary depending on the selected option and execution mode. ### Attack Path 1. The attacker supplies a `max_videos` value containing a valid initial number followed by additional whitespace-separated `yt-dlp` options. 2. The script builds one scalar string containing `--playlist-end`, the initial number, and the injected options. 3. Unquoted expansion splits that string into separate arguments. 4. `yt-dlp` parses the additional words as genuine command-line options. 5. The attacker alters discovery behavior and may invoke filesystem-writing or command-related features exposed by the installed `yt-dlp` release. ### Impact Assessment At mini ...[truncated 446 chars]
Remediation
View remediation
&2 exit 2 fi PLAYLIST_OPTS=(--playlist-end "$MAX_VIDEOS") fi yt-dlp \ --flat-playlist \ -J \ --js-runtimes node \ "${PLAYLIST_OPTS[@]}" \ -- \ "$CHANNEL_URL" > "$PLAYLIST_FILE" ``` The validation should also impose a reasonable upper bound to prevent accidental or deliberate resource exhaustion. Use arrays for all dynamically assembled command arguments and place `--` before untrusted positional URLs where the invoked tool supports it. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
bin/extract.sh:29
Finding

Predictable Shared Temporary Files Enable Symlink and Cross-Run Attacks

Content
View full analysis
/tmp/playlist.json || { echo "Error: Failed to fetch playlist/channel info" exit 1 } # Normalize to entries array (handle single-video case) if jq -e '.entries' /tmp/playlist.json >/dev/null 2>&1; then ENTRIES_JSON=$(jq '.entries' /tmp/playlist.json) else # Single video: root is the video object, wrap in array ENTRIES_JSON="[$(cat /tmp/playlist.json)]" fi ``` ```bash SUBTITLE_BASE="/tmp/$VIDEO_ID" ``` ```bash SUBTITLE_FILE=$(ls /tmp/$VIDEO_ID*.srt 2>/dev/null | head -n1) ``` ```bash rm -f "$SUBTITLE_FILE" "${SUBTITLE_FILE}.auto" 2>/dev/null || true ``` ### Technical Analysis The script uses globally predictable names in the shared `/tmp` directory. It neither creates a private temporary directory nor verifies ownership and file type before opening, reading, or deleting these paths. The shell redirection to `/tmp/playlist.json` follows an existing symbolic link. A local attacker can therefore pre-create that path as a symlink to another file writable by the Skill account. Redirection opens the symlink target with truncation before `yt-dlp` executes. Subtitle files are similarly based only on a public video identifier. The wildcard lookup can select a file created by another user or a concurrent run. This permits data substitution, cross-run interference, and processing or removal of an unintended matching path. Concurrent Skill invocations also overwrite and consume the same playlist metadata file. ### Attack Path 1. A local attacker predicts the temporary path `/tmp/playlist.json`. 2. The attacker creates that path as a symbolic link to a file writable by the account that will run the Skill. 3. The victim invokes the Skill. 4. Shell redirection follows the symlink ...[truncated 711 chars]
Remediation
View remediation
&2 exit 1 } chmod 700 "$TMP_DIR" trap 'rm -rf -- "$TMP_DIR"' EXIT PLAYLIST_FILE="$TMP_DIR/playlist.json" SUBTITLE_BASE="$TMP_DIR/$VIDEO_ID" ``` Then: 1. Replace every `/tmp/playlist.json` reference with `"$PLAYLIST_FILE"`. 2. Restrict subtitle searches to `"$TMP_DIR"`. 3. Avoid parsing `ls`; use a safely quoted array or `find` with strict filename constraints. 4. Verify that selected files are regular files owned by the current process context. 5. Apply `umask 077` before creating temporary or output files. 6. Use the single cleanup trap instead of deleting wildcard-selected shared paths. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bin/extract.sh:115
Finding

Untrusted Transcript Metadata Can Trigger CSV Formula Injection

Content
View full analysis
"$OUTPUT_FILE" fi ESCAPED_TRANSCRIPT=$(echo "$TRANSCRIPT" | sed 's/"/""/g') echo "\"$VIDEO_ID\",\"$TITLE\",\"$VIDEO_URL\",\"$UPLOAD_DATE\",$DURATION,\"$ESCAPED_TRANSCRIPT\",$IS_AUTO" >> "$OUTPUT_FILE" ;; ``` ### Technical Analysis Video titles and transcript text originate from remotely controlled YouTube content. Although quotation marks in the transcript are doubled, the code does not neutralize values beginning with spreadsheet formula indicators such as `=`, `+`, `-`, or `@`. Quoting a CSV field does not reliably prevent spreadsheet applications from interpreting its content as a formula. A malicious channel owner can therefore place formula-like content in a title or subtitle. When a user opens the generated CSV in affected spreadsheet software, the application may evaluate that content. The title and other string fields are also inserted without proper CSV quote escaping. A title containing quotation marks can terminate or alter field boundaries, produce malformed rows, and help position attacker-controlled content in a formula-interpreted cell. ### Attack Path 1. An attacker controls a YouTube channel, video title, or subtitle track. 2. The attacker supplies a title or subtitle value beginning with a spreadsheet formula indicator. 3. The victim exports the channel using CSV output. 4. The script writes the attacker-controlled value without formula neutralization; title quotation marks are also not escaped. 5. The victim opens the CSV in spreadsheet software. 6. The spreadsheet may evaluate the malicious cell according to its formula and external-data handling policies. ### Impact Assessment Potential impact d ...[truncated 424 chars]
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script constructs an output path and immediately truncates the target file with > "$OUTPUT_FILE", which can erase prior extracted data. Although the script logs progress later, there is no confirmation prompt, overwrite warning, or nearby comment disclosing that existing output will be replaced.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.