Back to skill

Security audit

Video Download FaaS

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims at a high level, but its isolation claim is not backed by the packaged files and its shared /tmp process state can expose URLs or let the wrong process be killed.

Review before installing. Use this only in a low-privilege account and avoid private, signed, or token-bearing URLs until session files are moved to a private directory with restrictive permissions, PID/session validation is added, and the isolation documentation is either implemented or corrected.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/kill-download.sh:24
Finding
Untrusted PID Files Allow Unauthorized Process Termination<![CDATA[ ## Vulnerability Details **File Location**: `scripts/kill-download.sh:24-61` **Vulnerability Type**: Untrusted process identifier and insufficient process ownership validation **Risk Level**: High ### Vulnerable Code ```bash SESSION_FILE="/tmp/${SESSION_ID}.session" PID_FILE="/tmp/${SESSION_ID}.pid" LOG_FILE="/tmp/${SESSION_ID}.log" if [ ! -f "$PID_FILE" ]; then echo "Error: Process not found for session: $SESSION_ID" exit 1 fi PID=$(cat "$PID_FILE") # Check if process exists if ! kill -0 "$PID" 2>/dev/null; then echo "Process already terminated (PID: $PID)" rm -f "$SESSION_FILE" "$PID_FILE" "$LOG_FILE" exit 0 fi echo "Stopping download process..." echo "Session: $SESSION_ID" echo "PID: $PID" if [ "$FORCE" = "--force" ]; then # Force kill kill -9 "$PID" 2>/dev/null echo "✅ Force killed process $PID" else # Graceful kill kill "$PID" 2>/dev/null sleep 2 # Check if still running if kill -0 "$PID" 2>/dev/null; then echo "Process still running, forcing kill..." kill -9 "$PID" 2>/dev/null fi echo "✅ Process stopped" fi ``` ### Technical Analysis The script trusts a PID read from a file under the shared `/tmp` directory. It does not validate that the file was created by the download script, that its contents are a positive decimal PID, or that the referenced process is the expected `yt-dlp` process belonging to the recorded session. The caller also controls `SESSION_ID`, which determines the PID file path. An attacker able to create or replace a corresponding file can insert the PID of an unrelated process. Negative process selectors are not rejected. For example, a PID value of `-1` can cause the shell's `kill` command to signal all processes that the executing account is permitted to signal. The `kill -0` check only establishes that a signalable matching process or process set exists. It does not establish ownership by this skill or bind the PID to the original proc ...[truncated 1753 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a private runtime directory owned by the executing account: ```bash umask 077 RUNTIME_DIR="${XDG_RUNTIME_DIR:-$HOME/.local/run}/video-download-faas" mkdir -p -- "$RUNTIME_DIR" chmod 700 -- "$RUNTIME_DIR" ``` 2. Strictly validate session identifiers against the generated format: ```bash [[ "$SESSION_ID" =~ ^video_dl_[0-9]+_[0-9]+$ ]] || exit 1 ``` 3. Validate the PID as a positive decimal integer and explicitly reject zero and negative values: ```bash [[ "$PID" =~ ^[1-9][0-9]*$ ]] || exit 1 ``` 4. Use the end-of-options marker for signal operations: ```bash kill -0 -- "$PID" kill -TERM -- "$PID" kill -KILL -- "$PID" ``` 5. Bind each session to the original process identity by recording and verifying: - PID. - Process start time from `/proc/<pid>/stat`. - Executable path or command identity. - Owning user. 6. Refuse to terminate the process if any recorded identity attribute differs. 7. Create state files atomically and reject symbolic links. 8. Run the skill as a dedicated, unprivileged account and never as root. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/download.sh:7
Finding
Predictable Files in Shared Temporary Directory Enable Symlink Overwrite and Session Tampering<![CDATA[ ## Vulnerability Details **File Location**: `scripts/download.sh:7-8, 20-22, 27-42` **Vulnerability Type**: Unsafe predictable temporary files and symbolic-link following **Risk Level**: High ### Vulnerable Code ```bash OUTPUT_DIR="${2:-$HOME/Downloads}" SESSION_NAME="video_dl_$(date +%s)_$$" # Generate unique session file SESSION_FILE="/tmp/${SESSION_NAME}.session" PID_FILE="/tmp/${SESSION_NAME}.pid" LOG_FILE="/tmp/${SESSION_NAME}.log" # Start download in background with nohup # Force MP4 output format nohup yt-dlp \ --no-warnings \ --progress \ --format "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" \ --merge-output-format mp4 \ --recode-video mp4 \ -o "${OUTPUT_DIR}/%(title)s.%(ext)s" \ "$URL" > "$LOG_FILE" 2>&1 & # Save PID PID=$! echo $PID > "$PID_FILE" # Save session info cat > "$SESSION_FILE" <<EOF { "session_id": "$SESSION_NAME", "pid": $PID, "url": "$URL", "output_dir": "$OUTPUT_DIR", "log_file": "$LOG_FILE", "pid_file": "$PID_FILE", "status": "running", "started_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" } EOF ``` ### Technical Analysis The script creates session, PID, and log files directly in the globally shared `/tmp` directory. Their names are derived from a timestamp with one-second resolution and the shell PID: ```text video_dl_<timestamp>_<pid>.<extension> ``` The files are opened through ordinary shell redirection. Shell redirection follows existing symbolic links and truncates the linked target where permissions allow. No private session directory, exclusive file creation, symbolic-link rejection, or restrictive `umask` is used. A local attacker who predicts the timestamp and PID, observes process creation patterns, or pre-creates a range of likely names can place symbolic links at the expected paths. When the download starts, the script follows those links while writing the log, PID, and JSON session data. The same shared files are subsequently trusted by the status a ...[truncated 1754 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set a restrictive permission mask before creating any state: ```bash umask 077 ``` 2. Replace predictable top-level `/tmp` files with a securely generated private directory: ```bash SESSION_DIR=$(mktemp -d "${TMPDIR:-/tmp}/video_dl.XXXXXXXXXX") || exit 1 chmod 700 -- "$SESSION_DIR" ``` 3. Store all session files beneath that directory: ```bash SESSION_FILE="$SESSION_DIR/session" PID_FILE="$SESSION_DIR/pid" LOG_FILE="$SESSION_DIR/log" ``` 4. Use creation mechanisms that fail if a file already exists and do not follow symbolic links. 5. Verify each state file with `lstat`-equivalent behavior before use and require: - A regular file. - Ownership by the current effective user. - No group or world access. - No symbolic links. 6. Write metadata to a temporary file in the private directory and atomically rename it into place. 7. Avoid predictable session identifiers as the sole authorization mechanism. Use a cryptographically random identifier generated from a secure source. 8. Execute the skill as a dedicated unprivileged account. 9. Add cleanup traps for interruption and failure while preserving logs only when explicitly requested. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/download.sh:20
Finding
Sensitive Download URLs and Logs Are Stored in Shared Temporary Storage<![CDATA[ ## Vulnerability Details **File Location**: `scripts/download.sh:20-22, 27-35, 39-54` **Vulnerability Type**: Sensitive information exposure through insufficiently protected temporary files **Risk Level**: Medium ### Vulnerable Code ```bash # Generate unique session file SESSION_FILE="/tmp/${SESSION_NAME}.session" PID_FILE="/tmp/${SESSION_NAME}.pid" LOG_FILE="/tmp/${SESSION_NAME}.log" # Start download in background with nohup # Force MP4 output format nohup yt-dlp \ --no-warnings \ --progress \ --format "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" \ --merge-output-format mp4 \ --recode-video mp4 \ -o "${OUTPUT_DIR}/%(title)s.%(ext)s" \ "$URL" > "$LOG_FILE" 2>&1 & # Save PID PID=$! echo $PID > "$PID_FILE" # Save session info cat > "$SESSION_FILE" <<EOF { "session_id": "$SESSION_NAME", "pid": $PID, "url": "$URL", "output_dir": "$OUTPUT_DIR", "log_file": "$LOG_FILE", "pid_file": "$PID_FILE", "status": "running", "started_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" } EOF # Return immediately with session info echo "✅ Download started in background" echo "" echo "Session ID: $SESSION_NAME" echo "PID: $PID" echo "Log: $LOG_FILE" ``` ### Technical Analysis The complete download URL is persisted in the session file, and all `yt-dlp` output is persisted in a log under `/tmp`. Download URLs can contain signed query parameters, access tokens, private media identifiers, or other credentials. Downloader diagnostics may also expose media metadata or authentication-related details. The script does not set `umask 077` or explicitly assign restrictive permissions. Consequently, confidentiality depends on the environment's existing `umask` and temporary-directory policy. Under a common `022` mask, newly created regular files may be readable by other local users. The filenames are also predictable and the script prints the log location. Although printing the path to the invoking user is expected behavior, p ...[truncated 1193 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Apply restrictive permissions before any file is created: ```bash umask 077 ``` 2. Store session state and logs in a private mode-`0700` runtime directory rather than directly under `/tmp`. 3. Explicitly enforce mode `0600` on metadata and log files. 4. Do not persist the full URL unless it is required for operation. 5. If a URL must be retained, redact sensitive components such as: - Query parameters. - User information. - Fragments. - Embedded access tokens. 6. Avoid displaying full sensitive URLs in status output. 7. Provide a configurable log-retention policy and securely remove state after completion or failure. 8. Treat downloader output as potentially sensitive and avoid retaining it by default. 9. Document that credentials should be supplied through protected mechanisms rather than embedded in URLs wherever the downloader supports such mechanisms. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill advertises FaaS/Firecracker-style isolation, but the documentation only shows direct host-side background execution and references isolation without demonstrating or enforcing it. This can mislead operators into treating untrusted video downloads as sandboxed when they may actually run yt-dlp and related tooling on the host, increasing exposure to parser bugs, unsafe post-processing, or operational misuse; the missing status/kill implementation also indicates the documented security/management model is incomplete.

Session Persistence

Medium
Category
Rogue Agent
Content
PID_FILE="/tmp/${SESSION_NAME}.pid"
LOG_FILE="/tmp/${SESSION_NAME}.log"

# Start download in background with nohup
# Force MP4 output format
nohup yt-dlp \
    --no-warnings \
Confidence
65% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
PID_FILE="/tmp/${SESSION_NAME}.pid"
LOG_FILE="/tmp/${SESSION_NAME}.log"

# Start download in background with nohup
# Force MP4 output format
nohup yt-dlp \
    --no-warnings \
Confidence
65% 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.

Missing User Warnings

Low
Confidence
86% confidence
Finding
This shell script deletes the session, PID, and log files after reporting a completed download. Although the cleanup is visible in code, there is no user-facing warning, confirmation, or explanatory comment indicating that checking status of a completed session will also remove tracking artifacts.

Static analysis

No suspicious patterns detected.