Back to skill

Security audit

Onnex YouTube

Security checks for vulnerabilities and agentic risk

Overview

This YouTube skill largely matches its media purpose, but it asks for broader Google account authority than its read-style features need and stores reusable OAuth tokens in a risky way.

Review before installing. Use this only with a Google/YouTube account you are comfortable exposing to the skill, and preferably after the publisher narrows OAuth scopes to read-only, removes the unrelated gogcli credential fallback, replaces pickle token storage with a safer format, documents token storage clearly, and pins dependencies. I did not find direct exfiltration, destructive actions, or prompt hijacking in the artifact, so this is Review rather than malicious.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/youtube.py:68
Finding

OAuth Scopes Grant Unnecessary YouTube Account Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/youtube.py:107
Finding

Unsafe Deserialization of Persistent OAuth Token File

Content
View full analysis
.pickle`, can obtain code execution the next time the user runs a command that calls `get_youtube_service()`. This finding requires the attacker to have a path to modify the token file or its containing directory. It does not independently provide remote access. Nevertheless, writable persistent state is a realistic trust boundary for desktop agents, shared systems, restored backups, and environments containing multiple extensions or local processes. ### Attack Path 1. The attacker gains the ability to write to the user's YouTube Skill configuration directory or replace a token file through another compromised process, malicious extension, unsafe backup, or incorrect filesystem permissions. 2. The attacker creates a malicious pickle whose deserialization routine executes an attacker-selected command or Python callable. 3. The malicious file is placed at the token path returned by `get_token_file()`. 4. The user invokes an API-backed command such as `search`, `video`, `comments`, `subscriptions`, or `playlists`. 5. `get_youtube_service()` opens the token file and calls `pickle.load()`. 6. The embedded re ...[truncated 529 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/youtube.py:2
Finding

Runtime Dependencies Are Not Pinned or Integrity Verified

Content
View full analysis
=3.10" # dependencies = [ # "google-api-python-client>=2.0.0", # "google-auth-oauthlib>=1.0.0", # "google-auth-httplib2>=0.1.0", # "youtube-transcript-api>=0.6.0", # ] # /// ``` ### Technical Analysis Every dependency uses an open-ended minimum-version constraint. Consequently, `uv run` may resolve a future package release that was not part of the reviewed Skill artifact. No reviewed lockfile or package hashes are included in the project to bind package names to specific distributions. Python dependency code executes in the Skill's process and may run at import time. A compromised publisher account, package registry incident, or malicious future release satisfying these constraints could therefore alter the effective code after the Skill has been reviewed. The listed package names do not show evidence of typosquatting or dependency confusion, and no currently malicious release was established during this audit. The vulnerability is the absence of reproducible and integrity-verified dependency resolution, not proof that the named dependencies are presently malicious. ### Attack Path 1. A dependency publisher account or package distribution channel is compromised, or a malicious compatible release is otherwise published. 2. The release version satisfies one of the broad `>=` constraints. 3. A user invokes the script in an environment where that version is selected during dependency resolution. 4. `uv` downloads and installs the unreviewed distribution. 5. Python imports the dependency when the script starts. 6. Malicious package initialization code executes with the privileges of the user running the Skill. ### Impact Assessment A malicious dependency executes inside the same process and security context as the Sk ...[truncated 336 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The metadata and description understate the actual capabilities by omitting OAuth authentication, access to authenticated/private YouTube account data, comment retrieval, and local token storage. This is dangerous because users and reviewers may grant or install the skill based on an incomplete understanding of the data it can access and persist, increasing the risk of over-privileged use and unintended exposure of personal account information.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The requested OAuth scopes include broad write-capable permissions (youtube and youtube.force-ssl) even though the implemented functionality is primarily read/list/download oriented. Overbroad scopes violate least privilege and make any token theft or misuse significantly more damaging because the credential could potentially modify or act on the user's YouTube account.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/youtube.py (reported line 87)May include surrounding context.

python
CONFIG_DIR = Path.home() / '.config' / 'youtube-skill'
CREDENTIAL_PATHS = [
    Path.home() / '.config' / 'youtube-skill' / 'credentials.json',
    Path.home() / '.config' / 'gogcli' / 'credentials.json',
]
DEFAULT_ACCOUNT = 'default'

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/youtube.py (reported line 128)May include surrounding context.

python
CONFIG_DIR = Path.home() / '.config' / 'youtube-skill'
CREDENTIAL_PATHS = [
    Path.home() / '.config' / 'youtube-skill' / 'credentials.json',
    Path.home() / '.config' / 'gogcli' / 'credentials.json',
]
DEFAULT_ACCOUNT = 'default'

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/youtube.py (reported line 134)May include surrounding context.

python
CONFIG_DIR = Path.home() / '.config' / 'youtube-skill'
CREDENTIAL_PATHS = [
    Path.home() / '.config' / 'youtube-skill' / 'credentials.json',
    Path.home() / '.config' / 'gogcli' / 'credentials.json',
]
DEFAULT_ACCOUNT = 'default'

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The script searches an additional unrelated path (~/.config/gogcli/credentials.json) for OAuth client secrets, creating unexpected cross-tool credential reuse. This broadens the trust boundary and can cause the skill to consume credentials intended for a different application, surprising users and potentially exposing or misusing credentials across tools.

Content

Scanner excerpt · scripts/youtube.py (reported line 88)May include surrounding context.

python
CONFIG_DIR = Path.home() / '.config' / 'youtube-skill'
CREDENTIAL_PATHS = [
    Path.home() / '.config' / 'youtube-skill' / 'credentials.json',
    Path.home() / '.config' / 'gogcli' / 'credentials.json',
]
DEFAULT_ACCOUNT = 'default'

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises network and shell-capable behavior but does not declare any explicit tool scope such as permissions or allowed-tools. That omission weakens least-privilege controls and makes it harder for reviewers and runtime policy engines to constrain what the skill may access, especially because the file also emphasizes trust signals like 'security reviewed' instead of enforceable restrictions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description emphasizes transcripts, downloads, and exploration, but the code also accesses authenticated personal YouTube data including subscriptions, playlists, liked videos, and the user's own channel. This mismatch increases privacy risk because users may authorize the skill without realizing it can enumerate account-level data beyond the advertised purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script silently reads and writes OAuth credentials and tokens to local files without clearly warning the user about storage location, persistence, or required protections. In a skill context, that can lead users to unknowingly leave reusable account tokens on disk, increasing exposure if the workstation is shared, backed up insecurely, or otherwise compromised.

Content

No source excerpt is available for this finding.

Insecure deserialization: pickle.load()

Medium
Category
Dangerous Code Execution
Confidence
93% confidence
Finding

pickle.load() will execute attacker-controlled objects during deserialization if the token file is replaced or tampered with. Because the file is loaded automatically from a predictable path in the user's home directory, any local compromise, unsafe file sharing, or symlink/path abuse could turn this into arbitrary code execution when the skill runs.

Content

Scanner excerpt · scripts/youtube.py (reported line 119)May include surrounding context.

python
creds = None
    if token_file.exists():
        with open(token_file, 'rb') as token:
            creds = pickle.load(token)

    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/youtube.py (reported line 585)May include surrounding context.

python
cmd.append(url)
    
    print(f"Downloading: {url}")
    subprocess.run(cmd)


def cmd_download_audio(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/youtube.py (reported line 609)May include surrounding context.

python
cmd.append(url)
    
    print(f"Downloading: {url}")
    subprocess.run(cmd)


def cmd_download_audio(args):

Static analysis

No suspicious patterns detected.