Back to skill

Security audit

Youtube Music Player

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its YouTube Music purpose, but it asks users to share reusable session cookies and stores sensitive local auth and daemon state with weakly documented protections.

Review carefully before installing. Use this only if you are comfortable with an agent handling a reusable YouTube/Google session cookie and storing it under .ytmusic. Prefer a dedicated low-risk account, avoid pasting cookies into chat where possible, remove auth with the provided auth remove command when done, and stop the playback daemon when you no longer need it.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/helper.py:184
Finding

Reusable YouTube Session Credentials Are Collected Through Chat and Command-Line Arguments

Content
View full analysis
Network Filter /browse and reload the page Open any matching request Copy the Cookie request header value Send the full Cookie string back to me ``` ```bash uv run --with ytmusicapi python scripts/helper.py auth setup --cookie '' uv run --with ytmusicapi python scripts/helper.py auth setup --cookies-file /path/to/cookies.json ``` ```python elif args.action == "setup": if getattr(args, "cookies_file", None): _import_cookies_json(args.cookies_file) else: cookie = args.cookie or sys.stdin.read().strip() if not cookie: bail("No cookie provided. Pass --cookie '' or --cookies-file cookies.json") headers = build_auth_from_cookie(cookie) _write_json(AUTH_FILE, headers) out({"status": "saved", "path": str(AUTH_FILE)}) ``` ```python pa.add_argument("--cookie", help="Raw Cookie header string (for setup)") pa.add_argument("--cookies-file", dest="cookies_file", help="JSON cookie export from a browser extension (for setup, e.g. Cookie-Editor)") ``` ### Technical Analysis A complete authenticated Google/YouTube `Cookie` header is a reusable session credential. The Skill explicitly instructs the user to send this credential to the agent and supports supplying it through the `--cookie` command-line option. Credentials submitted through an agent conversation may be retained in ...[truncated 1635 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/helper.py:87
Finding

Authentication Credentials Are Stored Without Explicitly Restrictive File Permissions

Content
View full analysis
None: path.parent.mkdir(parents=True, exist_ok=True) with tempfile.NamedTemporaryFile("w", encoding="utf-8", delete=False, dir=path.parent) as tmp: json.dump(data, tmp, indent=2, ensure_ascii=False) tmp.write("\n") Path(tmp.name).replace(path) ``` ```python def build_auth_from_cookie(cookie_string: str) -> dict: """Compute SAPISIDHASH and build the auth headers dict from a raw cookie string.""" sapisid = None for part in cookie_string.split(";"): part = part.strip() if part.startswith("SAPISID="): sapisid = part.split("=", 1)[1] break if not sapisid: # Try __Secure-3PAPISID as fallback for part in cookie_string.split(";"): part = part.strip() if part.startswith("__Secure-3PAPISID="): sapisid = part.split("=", 1)[1] break if not sapisid: bail("SAPISID not found in cookie string") ts = int(time.time()) sha1 = hashlib.sha1(f"{ts} {sapisid} https://music.youtube.com".encode()).hexdigest() return { "Authorization": f"SAPISIDHASH {ts}_{sha1}", "Cookie": cookie_string.strip(), "X-Goog-AuthUser": "0", "x-origin": "https://music.youtube.com", } ``` ```python headers = build_auth_from_cookie(cookie) _write_json(AUTH_FILE, headers) ``` ### Technical Analysis The generated `.ytmusic/auth.json` file stores the complete Cookie header and an Authorization value in plaintext. The write helper creates the parent directory and temporary file without explicitly enforcing owner-only permissions on the directory or final credential file. `NamedTemporaryFile` common ...[truncated 1515 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/player_daemon.py:528
Finding

Playback Daemon Bearer Token Is Persisted Without Explicit Access Restrictions

Content
View full analysis
None: path.parent.mkdir(parents=True, exist_ok=True) tmp = path.with_suffix(path.suffix + ".tmp") tmp.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n") tmp.replace(path) ``` ```python def _auth_ok(self) -> bool: return self.headers.get("X-YTMUSIC-Token") == self.server.token ``` ```python token = secrets.token_hex(16) runtime = YTMusicRuntime(args.user_data_dir) server = PlayerHTTPServer((args.host, args.port), runtime=runtime, token=token) state = { "pid": os.getpid(), "host": args.host, "port": server.server_address[1], "token": token, "profile_dir": str(args.user_data_dir), "started_at": int(time.time()), "mode": "playwright-persistent", } _write_json(STATE_FILE, state) ``` ### Technical Analysis The daemon correctly defaults to loopback binding and uses a randomly generated 128-bit bearer token. However, it stores that token in `.ytmusic/player-daemon.json` through `Path.write_text()` without explicitly enforcing owner-only permissions on the state file or its parent directory. Possession of this token is sufficient to authenticate to the daemon. A local party that reads the state file can derive the active port and send authorized requests to `/health`, `/command`, or `/shutdown`. Loopback binding prevents direct remote access, but it does not protect against other local users or compromised processes running under an account with file access. The daemon also supports an explicit `--host` option. If launched manually with a non-loopback host while the token is exposed, the control surface could become accessible from other hosts. ### Attack Path 1. The playback daemon starts and creates ...[truncated 1056 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:35
Finding

Runtime Dependencies Are Dynamically Retrieved Without Version or Integrity Pinning

Content
View full analysis
" --type songs --limit 5 uv run --with ytmusicapi python scripts/helper.py search "" --type artists --limit 3 uv run --with ytmusicapi python scripts/helper.py search "" --type albums --limit 3 ``` ```bash uv run --with playwright python scripts/player.py daemon-start uv run --with playwright python scripts/player.py open uv run --with playwright python scripts/player.py play uv run --with playwright python scripts/player.py pause uv run --with playwright python scripts/player.py status ``` ```markdown - `ytmusicapi` is pulled on demand via `uv run --with ytmusicapi ...` - `playwright` is pulled on demand via `uv run --with playwright ...` ``` ### Technical Analysis The documented execution model directs `uv` to resolve and execute `ytmusicapi` and `playwright` dynamically without exact versions, hashes, or a committed lockfile. Consequently, the code that runs can change after the Skill package has been reviewed. This is a supply-chain risk rather than evidence that the currently named packages are malicious. A compromised upstream release, package-index account takeover, unsafe alternate package index, or incompatible future version could execute with the same privileges as the Skill. Those privileges are significant: dependency code runs in the process that handles `.ytmusic/auth.json`, imported cookie files, upload paths, user data directories, and the persistent browser profile. ### Attack Path 1. The user invokes one of the documented `uv run --with` commands. 2. `uv` resolves an unpinned dependency from the configured package source. 3. A compromised or unexpectedly modified depend ...[truncated 853 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (40)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

Even if most music features exist in referenced scripts, the skill text introduces a persistent Playwright daemon and local control mechanism that are not clearly disclosed in the top-level purpose. Undisclosed background automation and service lifecycle behavior are risky because they create hidden persistence and execution surfaces beyond simple music queries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

Even if most music features exist in referenced scripts, the skill text introduces a persistent Playwright daemon and local control mechanism that are not clearly disclosed in the top-level purpose. Undisclosed background automation and service lifecycle behavior are risky because they create hidden persistence and execution surfaces beyond simple music queries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Even if most music features exist in referenced scripts, the skill text introduces a persistent Playwright daemon and local control mechanism that are not clearly disclosed in the top-level purpose. Undisclosed background automation and service lifecycle behavior are risky because they create hidden persistence and execution surfaces beyond simple music queries.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 20)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 39)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 40)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 41)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 110)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 111)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 117)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 118)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 119)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 120)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 121)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 122)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 123)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 124)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 125)May include surrounding context.

md
- `scripts/helper.py`: search, library, playlists, lyrics, ratings, account

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill instructs users to provide a full Cookie header or cookies export without clearly warning that these are highly sensitive authentication credentials that can enable account access. In context, this is especially dangerous because the skill is for a consumer media service, where users may not realize they are being asked to hand over reusable session secrets in chat.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Requesting that a user send their full YouTube Music Cookie header back in chat is direct solicitation of sensitive authentication material. An intercepted, logged, or mishandled cookie can allow account takeover or unauthorized access, and the surrounding instructions normalize this unsafe practice rather than containing it.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The helper explicitly instructs the agent to ask the user for a full Cookie string from a logged-in music.youtube.com request. In a conversational agent setting this is extremely dangerous because the user is being told to disclose live session credentials directly to the model, creating a direct path to account compromise, credential replay, and unauthorized access beyond the intended YouTube Music actions.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The reply templates provide step-by-step guidance for extracting a full Cookie request header and sending it back to the agent. This is not merely sensitive-data handling; it operationalizes credential exfiltration by normalizing the transfer of high-value authentication secrets through the chat interface.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

These setup steps direct the user to open DevTools, copy the Cookie header from a logged-in request, and send it to the agent. In the context of an AI-operated skill, this is a severe secret-handling flaw because it trains the user to exfiltrate account session material into a channel that may be logged, retained, or accessible beyond the local browser.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/player.py (reported line 120)May include surrounding context.

python
stdout=log_file,
            stderr=subprocess.STDOUT,
            start_new_session=True,
            env=os.environ.copy(),
        )

    return _wait_for_daemon(time.time() + YTM_DAEMON_START_TIMEOUT)

Static analysis

No suspicious patterns detected.