Back to skill

Security audit

yt2gdrive

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs the stated YouTube-to-Google-Drive sync, but its dry-run mode is misleading and can still download files and run local cleanup.

Install only if you are comfortable with a shell script downloading YouTube media, uploading to your configured Google Drive remote, and optionally installing a daily macOS LaunchAgent. Do not rely on --dry-run as non-mutating; review LOCAL_DIR and use --keep-local if you do not want local cleanup.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/yt2gdrive.sh:42
Finding

Dry-run mode performs real downloads and destructive local cleanup

Content
View full analysis

Vulnerability Details

File Location: scripts/yt2gdrive.sh, lines 42–46, 99–116, 145–149, and 154–164
Vulnerability Type: Dry-run safety violation and unintended file deletion
Risk Level: Medium

Vulnerable Code

bash
DRY_RUN=""
KEEP_LOCAL=""
for arg in "$@"; do
    case $arg in
        --dry-run)  DRY_RUN="--dry-run"; echo "⚡ DRY RUN 模式,不实际下载/上传" ;;
        --keep-local) KEEP_LOCAL=1 ;;
    esac
done
bash
yt-dlp \
    --download-archive "$ARCHIVE_FILE" \
    --dateafter "$date_min" \
    --match-filter "duration < $MAX_DURATION" \
    --break-on-reject \
    --playlist-end "$MAX_DOWNLOADS" \
    "${media_args[@]}" \
    --no-overwrites \
    --ignore-errors \
    --no-warnings \
    --progress \
    -o "${LOCAL_DIR}/%(uploader)s/%(upload_date>%Y%m%d)s - %(title).120s.%(ext)s" \
    "$url" \
    >> "$LOG_FILE" 2>&1 || log "⚠️  频道 $channel_name 部分下载失败(已记录)"
bash
rclone copy "$LOCAL_DIR/" "${REMOTE_NAME}:${REMOTE_PATH}/" \
    --fast-list \
    --transfers=4 \
    --checkers=8 \
    --bwlimit="$BWLIMIT" \
    --log-file="$LOG_FILE" \
    --log-level=INFO \
    $DRY_RUN
bash
cleanup_local() {
    if [[ -n "$KEEP_LOCAL" ]]; then
        log "📦 本地文件保留(--keep-local)"
        return 0
    fi

    log "🧹 清理本地 ${CLEANUP_DAYS} 天前的文件..."
    find "$LOCAL_DIR" -type f -mtime "+${CLEANUP_DAYS}" -delete 2>/dev/null || true
    find "$LOCAL_DIR" -type d -empty -delete 2>/dev/null || true
    log "🧹 清理完成"
}

Technical Analysis

The --dry-run option is stored in DRY_RUN and supplied only to rclone copy. The yt-dlp invocation receives no simulation option, so it performs actual network requests, media downloads, conversion, archive updates, and local writes.

The script subsequently invokes cleanup_local regardless of dry-run status. Unless --keep-local is also supplied, the cle ...[truncated 1514 chars]

Remediation
View remediation

Remediation Suggestions

  1. Implement dry-run consistently across every mutating stage:
    • Pass --simulate to yt-dlp, or skip the download function entirely.
    • Do not update the download archive in preview mode.
    • Return before cleanup_local when dry-run is enabled.
  2. Represent optional command arguments with an array rather than an unquoted scalar:
    bash
    dry_run_args=()
    if [[ "$DRY_RUN" == "1" ]]; then
        dry_run_args=(--dry-run)
    fi
    
  3. Add an explicit guard to cleanup:
    bash
    cleanup_local() {
        if [[ "$DRY_RUN" == "1" ]]; then
            log "Dry run: skipping local cleanup"
            return 0
        fi
        # Existing cleanup logic
    }
    
  4. Validate LOCAL_DIR before deletion:
    • Reject empty values, /, $HOME, and other unexpectedly broad paths.
    • Resolve the canonical path and require it to match an application-specific staging directory or an explicitly approved location.
  5. Consider requiring explicit confirmation before cleanup when LOCAL_DIR differs from the default.
  6. Add automated tests confirming that dry-run mode creates, modifies, uploads, and deletes no files.
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose focuses on media sync, but the skill also documents persistence behavior through install_launchd.sh and daily scheduled execution. Hidden or under-disclosed persistence is risky because it causes recurring background execution, repeated network access, log writing, uploads, and cleanup actions beyond a one-time sync expectation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The markdown describes behavior that downloads media, uploads it to a cloud service, schedules automatic syncing, and automatically cleans up local files. While the features are clear, there is no explicit caution that the skill will transfer content to Google Drive and may delete local copies, which could affect user data handling and system state.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill advertises shell-capable behavior but does not declare any tool scope or permissions boundaries. That makes its execution surface ambiguous and can cause an agent or user to run filesystem, network, and process-launching actions without an explicit trust decision, especially since the documented workflow invokes shell scripts and external binaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The documentation describes synchronization but does not prominently warn that the skill uploads downloaded media to a cloud remote and may automate recurring sync and local cleanup. In practice, this can affect user storage, bandwidth, retained local data, and cloud account contents, so insufficient disclosure increases the chance of unintended data handling.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 81)May include surrounding context.

md
# install_launchd.sh — 安装 macOS 每日定时任务(launchd)
# 用法: install_launchd.sh [小时] [分钟]   # 默认 07:30
#
# 卸载: launchctl unload ~/Library/LaunchAgents/com.user.yt2gdrive.plist

set -euo pipefail

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 5)May include surrounding context.

sh
# install_launchd.sh — 安装 macOS 每日定时任务(launchd)
# 用法: install_launchd.sh [小时] [分钟]   # 默认 07:30
#
# 卸载: launchctl unload ~/Library/LaunchAgents/com.user.yt2gdrive.plist

set -euo pipefail

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 12)May include surrounding context.

sh
# install_launchd.sh — 安装 macOS 每日定时任务(launchd)
# 用法: install_launchd.sh [小时] [分钟]   # 默认 07:30
#
# 卸载: launchctl unload ~/Library/LaunchAgents/com.user.yt2gdrive.plist

set -euo pipefail

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 19)May include surrounding context.

sh
# install_launchd.sh — 安装 macOS 每日定时任务(launchd)
# 用法: install_launchd.sh [小时] [分钟]   # 默认 07:30
#
# 卸载: launchctl unload ~/Library/LaunchAgents/com.user.yt2gdrive.plist

set -euo pipefail

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 20)May include surrounding context.

sh
# install_launchd.sh — 安装 macOS 每日定时任务(launchd)
# 用法: install_launchd.sh [小时] [分钟]   # 默认 07:30
#
# 卸载: launchctl unload ~/Library/LaunchAgents/com.user.yt2gdrive.plist

set -euo pipefail

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 46)May include surrounding context.

sh
# install_launchd.sh — 安装 macOS 每日定时任务(launchd)
# 用法: install_launchd.sh [小时] [分钟]   # 默认 07:30
#
# 卸载: launchctl unload ~/Library/LaunchAgents/com.user.yt2gdrive.plist

set -euo pipefail

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 12)May include surrounding context.

sh
HOUR="${1:-7}"
MINUTE="${2:-30}"
SCRIPT="$(cd "$(dirname "$0")/.." && pwd)/scripts/yt2gdrive.sh"
PLIST="$HOME/Library/LaunchAgents/com.user.yt2gdrive.plist"

# 确保 LaunchAgents 目录存在
mkdir -p "$HOME/Library/LaunchAgents"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 19)May include surrounding context.

sh
HOUR="${1:-7}"
MINUTE="${2:-30}"
SCRIPT="$(cd "$(dirname "$0")/.." && pwd)/scripts/yt2gdrive.sh"
PLIST="$HOME/Library/LaunchAgents/com.user.yt2gdrive.plist"

# 确保 LaunchAgents 目录存在
mkdir -p "$HOME/Library/LaunchAgents"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 49)May include surrounding context.

sh
HOUR="${1:-7}"
MINUTE="${2:-30}"
SCRIPT="$(cd "$(dirname "$0")/.." && pwd)/scripts/yt2gdrive.sh"
PLIST="$HOME/Library/LaunchAgents/com.user.yt2gdrive.plist"

# 确保 LaunchAgents 目录存在
mkdir -p "$HOME/Library/LaunchAgents"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 51)May include surrounding context.

sh
HOUR="${1:-7}"
MINUTE="${2:-30}"
SCRIPT="$(cd "$(dirname "$0")/.." && pwd)/scripts/yt2gdrive.sh"
PLIST="$HOME/Library/LaunchAgents/com.user.yt2gdrive.plist"

# 确保 LaunchAgents 目录存在
mkdir -p "$HOME/Library/LaunchAgents"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 53)May include surrounding context.

sh
HOUR="${1:-7}"
MINUTE="${2:-30}"
SCRIPT="$(cd "$(dirname "$0")/.." && pwd)/scripts/yt2gdrive.sh"
PLIST="$HOME/Library/LaunchAgents/com.user.yt2gdrive.plist"

# 确保 LaunchAgents 目录存在
mkdir -p "$HOME/Library/LaunchAgents"

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

At this line the script begins writing a LaunchAgent plist into the user's persistent launchd directory, which establishes automatic execution on a schedule. In this skill context that persistence is expected, but it is still security-relevant because it survives the current session and will repeatedly execute another script without further approval.

Content

Scanner excerpt · scripts/install_launchd.sh (reported line 17)May include surrounding context.

sh
# 确保 LaunchAgents 目录存在
mkdir -p "$HOME/Library/LaunchAgents"

cat > "$PLIST" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code writes a LaunchAgent plist into the user's Library and then activates it with launchctl, creating a persistent scheduled task. Although the script prints a success message afterward, there is no confirmation prompt or pre-action warning before the file write and service load occur.

Content

No source excerpt is available for this finding.

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/install_launchd.sh (reported line 49)May include surrounding context.

sh
</plist>
EOF

chmod 644 "$PLIST"
launchctl unload "$PLIST" 2>/dev/null || true
launchctl load "$PLIST"
echo "✅ launchd 任务已安装:每天 ${HOUR}:${MINUTE} 运行 $SCRIPT"

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

launchctl load "$PLIST" activates the newly written LaunchAgent, making the scheduled task persistent and automatically executable in future sessions. In a benign backup/sync tool this may be intended, but from a security perspective it is the key persistence action and should be treated as sensitive because any compromise of the referenced script would gain recurring execution.

Content

Scanner excerpt · scripts/install_launchd.sh (reported line 50)May include surrounding context.

sh
EOF

chmod 644 "$PLIST"
launchctl unload "$PLIST" 2>/dev/null || true
launchctl load "$PLIST"
echo "✅ launchd 任务已安装:每天 ${HOUR}:${MINUTE} 运行 $SCRIPT"
echo "   卸载: launchctl unload $PLIST"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install_launchd.sh (reported line 51)May include surrounding context.

sh
chmod 644 "$PLIST"
launchctl unload "$PLIST" 2>/dev/null || true
launchctl load "$PLIST"
echo "✅ launchd 任务已安装:每天 ${HOUR}:${MINUTE} 运行 $SCRIPT"
echo "   卸载: launchctl unload $PLIST"

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documentation presents all user-facing instructions in Chinese and does not indicate that other languages are available. This can violate a language/locale policy when a specific language is imposed without user choice or documented justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.