Back to skill

Security audit

YouTube Channel Parse

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its YouTube research purpose, but it uses insecure download settings and has weak boundaries around URLs, cookies, dependencies, and output paths.

Review this skill before installing. Run it only in an isolated workspace, avoid browser-cookie options unless explicitly needed, do not use it for sensitive or proprietary videos, and treat generated files as persistent local artifacts. Prefer pinned dependencies and remove the default certificate-bypass behavior before relying on its outputs.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/transcribe_with_fallback.py:238
Finding

Unrestricted Caption URL Fetch Enables SSRF and Local File Disclosure

Content
View full analysis
tuple[str, str]: for track in record.get("caption_urls", []): if not isinstance(track, dict): continue url = str(track.get("url") or "").strip() ext = str(track.get("ext") or "").strip() if not url or not ext: continue try: def read_payload() -> str: with urllib.request.urlopen(url, timeout=timeout_seconds) as response: return response.read().decode("utf-8", errors="ignore") payload = with_retries( read_payload, retries=retries, delay_seconds=delay_seconds, ) except Exception as exc: # noqa: BLE001 continue text = caption_payload_to_text(ext, payload) if text: label = track.get("category") or "caption" return text, f"{label}-url:{ext}" ``` ### Technical Analysis The script accepts `caption_urls` from the input dataset and passes each URL directly to `urllib.request.urlopen`. It does not validate: - The URL scheme. - Whether the destination belongs to YouTube or an expected Google caption service. - Whether the resolved address is private, loopback, link-local, or otherwise internal. - Whether redirects remain within an approved destination set. Because `urllib` supports schemes other than HTTPS, a crafted input can cause the process to retrieve internal HTTP resources or read local files through a `file://` URL. Retrieved content is treated as transcript text and subsequently written into transcript and JSON report artifacts. This network behavior exceeds the minimum p ...[truncated 1347 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/transcribe_with_fallback.py:372
Finding

Unsanitized Output Prefix and Video ID Permit Writes Outside the Output Directory

Content
View full analysis
None: args = parse_args() output_dir = Path(args.output_root) / args.output_prefix transcript_dir = transcripts_dir(output_dir) audio_dir = output_dir / "audio" payload, records = load_records(Path(args.input_json)) if args.limit is not None: records = records[: args.limit] enriched_records: list[dict] = [] total = len(records) for index, record in enumerate(records, start=1): video_id = record["video_id"] languages = transcript_languages(record, args) transcript_path = transcript_dir / f"{video_id}.txt" ``` The same output construction appears in the other scripts: ```python output_dir = Path(args.output_root) / args.output_prefix ``` Per-video Markdown paths are also constructed from input-record identifiers: ```python for record in records: note_path = transcript_path / f"{record['video_id']}.md" ``` ### Technical Analysis Neither `output_prefix` nor `video_id` is constrained to a safe filename component. An absolute `output_prefix` causes `pathlib` to discard the preceding output root. A prefix containing `..` can traverse to parent directories. Similarly, an absolute or traversal-containing `video_id` can cause transcript or Markdown output to escape its intended subdirectory. Directory creation and file writes then occur without verifying that the resolved destination remains under the configured output root. The vulnerable values originate from command-line arguments or reusable input JSON, so exploitation does not require command injection. ### Attack Path An output-prefix attack can proceed as fol ...[truncated 1273 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_channel.py:66
Finding

Certificate Verification Is Disabled for Every yt-dlp Request

Content
View full analysis
dict[str, Any]: stdout = run_command( [ "yt-dlp", "--no-check-certificates", "--flat-playlist", "--dump-single-json", channel_videos_url(channel_url), ] ) return json.loads(stdout) ``` The same option is unconditionally included in metadata, subtitle, and audio commands: ```python cmd = [ "yt-dlp", "--no-check-certificates", "--skip-download", "--write-auto-subs", "--write-subs", ... ] ``` ```python cmd = [ "yt-dlp", "--no-check-certificates", "-f", "bestaudio", ... ] ``` ### Technical Analysis The `--no-check-certificates` option disables TLS certificate verification. Although the documentation states that this option should be used only when required by the environment, the scripts include it in every `yt-dlp` invocation with no opt-in control. This removes server-authentication guarantees from metadata, subtitle, and audio retrieval. It is particularly concerning when the optional cookie features are enabled because authenticated requests may also traverse a connection that does not validate the remote certificate. Disabling certificate validation by default is not necessary for the declared YouTube retrieval functionality and therefore exceeds the minimum relaxation required for ordinary environments. ### Attack Path 1. A user runs the Skill on an untrusted or compromised network. 2. An attacker capable of intercepting DNS or network traffic presents an invalid or attacker-controlled TLS ce ...[truncated 844 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
references/dependencies.md:8
Finding

Runtime Dependencies Are Installed and Executed Without Version or Integrity Pinning

Content
View full analysis
.py ... ``` ## Script Chain Use the bundled scripts in this order: ```bash uv run --with yt-dlp python scripts/fetch_channel.py ... uv run --with yt-dlp --with youtube-transcript-api --with faster-whisper python scripts/transcribe_with_fallback.py ... uv run python scripts/build_report.py ... ``` ``` The README also recommends an unattended global installation: ```bash npx skills add ulyanas/product-research-skills --skill product-research-suite -g -y ``` The persistent fallback is likewise unpinned: ```bash python3 -m pip install faster-whisper ``` ### Technical Analysis These commands resolve and execute the current package versions available from external registries. The project does not provide a lockfile, exact versions, hashes, or integrity-verification procedure. Consequently, the effective executable code can change after the Skill has been audited. A compromised upstream package, malicious release, registry-account takeover, or unexpected breaking update could execute arbitrary code with the user's privileges. Temporary installation through `uv run` reduces persistence compared with a manual system installation, but it does not address package authenticity or reproducibility. The global unattended `npx` command increases the potential installation scope. ### Attack Path 1. An attacker compromises an upstream package, maintainer account, distribution channel, or dependency release. 2. The user follows the documented unpinned `uv`, `pip`, o ...[truncated 805 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/transcribe_with_fallback.py:38
Finding

Browser-Wide Cookie Extraction Exceeds Least-Privilege Requirements

Content
View full analysis
list[str]: auth_args: list[str] = [] if args.cookies: auth_args.extend(["--cookies", args.cookies]) if args.cookies_from_browser: auth_args.extend(["--cookies-from-browser", args.cookies_from_browser]) return auth_args ``` The documentation encourages this recovery method: ```markdown When cookies are available in the environment, prefer passing them to `yt-dlp`. Supported recovery options: - `--cookies /path/to/cookies.txt` - `--cookies-from-browser ` ``` ### Technical Analysis The browser-cookie option asks an external executable to access a browser's cookie database. Depending on the browser and `yt-dlp` behavior, this may expose a substantially broader credential store than the specific YouTube session data needed for a restricted video. The declared public-video analysis workflow does not ordinarily require authenticated browser state. Browser-wide credential access should therefore be an exceptional, explicitly authorized operation rather than the preferred recovery method. The ri ...[truncated 1348 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The implemented behavior is limited to retrieving YouTube metadata/inventory for channels or individual videos, normalizing records, filtering by metadata/date-like criteria, and exporting structured JSON/markdown. That aligns with the 'fetch' and 'filter' portions of the description. However, the description also prominently claims transcription, transcript collection, and summarization capabilities, none of which appear in this code chunk. There is no downloading of media, no speech-to-text, no subtitle retrieval, no transcript fields being fetched here, and no summarization logic. Because these are material declared capabilities rather than incidental details, the description overstates what this code actually does.

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 148)May include surrounding context.

md
- `transcribe_with_fallback.py` for transcript API attempts, `yt-dlp` audio download, and local Whisper transcription

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

Advising use of yt-dlp --no-check-certificates disables TLS certificate validation, which can allow man-in-the-middle interception or content tampering during metadata, subtitle, or media retrieval. In a network-fetching skill that downloads remote content and may feed it into downstream processing, this weakens transport security and can expose users to malicious or altered inputs.

Content

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

uv run --with yt-dlp --with youtube-transcript-api --with faster-whisper python scripts/

text

Pass `--no-check-certificates` to `yt-dlp` when the environment requires it.

Read `references/dependencies.md` for command patterns and dependency notes.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
94% confidence
Finding

Recommending --no-check-certificates disables TLS certificate validation for yt-dlp connections, which weakens transport security and enables man-in-the-middle interception or tampering when used on untrusted networks. In a skill that retrieves remote media and metadata, this increases the risk of poisoned content, credential leakage, and silent downgrade of connection integrity.

Content

Scanner excerpt · references/dependencies.md (reported line 129)May include surrounding context.

md
Prefer `uv run --with faster-whisper` over manual installation when possible.

Use `--no-check-certificates` with `yt-dlp` when the environment requires it.

Use multilingual Whisper models such as `tiny` or `small` for general YouTube transcription.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Using yt-dlp with --no-check-certificates disables TLS certificate validation for network connections. That allows a man-in-the-middle attacker or hostile network environment to tamper with the fetched channel inventory or intercept requests, undermining the integrity and confidentiality of the data source.

Content

Scanner excerpt · scripts/fetch_channel.py (reported line 71)May include surrounding context.

python
stdout = run_command(
        [
            "yt-dlp",
            "--no-check-certificates",
            "--flat-playlist",
            "--dump-single-json",
            channel_videos_url(channel_url),

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

This yt-dlp invocation also disables certificate checks while fetching per-video metadata from a channel. In a skill whose purpose is to collect and summarize remote content, trusting unauthenticated HTTPS responses makes downstream summaries and structured outputs vulnerable to tampering by network attackers.

Content

Scanner excerpt · scripts/fetch_channel.py (reported line 83)May include surrounding context.

python
def fetch_channel_details(channel_url: str, since_date: str | None, until_date: str | None) -> list[dict[str, Any]]:
    cmd = [
        "yt-dlp",
        "--no-check-certificates",
        "--skip-download",
        "--dump-json",
        "--quiet",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Disabling certificate validation for single-video metadata fetches creates the same integrity risk for individual video analysis. Because this skill produces reusable summaries and filtered outputs, tampered metadata could mislead users or contaminate later processing based on falsified remote content.

Content

Scanner excerpt · scripts/fetch_channel.py (reported line 107)May include surrounding context.

python
stdout = run_command(
        [
            "yt-dlp",
            "--no-check-certificates",
            "--dump-single-json",
            video_url,
        ]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Using yt-dlp with --no-check-certificates disables TLS certificate validation for remote content retrieval, making the transcript/subtitle download path vulnerable to man-in-the-middle interception or tampering. In this skill, downloaded subtitle text is later trusted as transcript content and persisted into output datasets, so a network attacker could inject false content or manipulate downstream summaries and analysis.

Content

Scanner excerpt · scripts/transcribe_with_fallback.py (reported line 284)May include surrounding context.

python
subtitle_languages = ["all"]
    cmd = [
        "yt-dlp",
        "--no-check-certificates",
        "--skip-download",
        "--write-auto-subs",
        "--write-subs",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Disabling certificate validation on the audio-download path allows a network attacker to tamper with the media fetched for local transcription. Because the resulting audio is fed into the transcription model and its output is written into structured results, this can poison transcripts and summaries and potentially expose the host to additional risk from malformed media handled by external tooling/decoders.

Content

Scanner excerpt · scripts/transcribe_with_fallback.py (reported line 321)May include surrounding context.

python
audio_dir.mkdir(parents=True, exist_ok=True)
    cmd = [
        "yt-dlp",
        "--no-check-certificates",
        "-f",
        "bestaudio",
        "-o",

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The guidance recommends supplying browser or file-based cookies to yt-dlp but does not warn that these cookies may contain authenticated session tokens and other sensitive account data. In an agent or shared execution environment, this can lead to credential exposure, unintended account access, or accidental persistence/logging of secrets.

Content

No source excerpt is available for this finding.

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/fetch_channel.py (reported line 63)May include surrounding context.

python
def run_command(cmd: list[str]) -> str:
    if shutil.which("yt-dlp") is None:
        raise DependencyError(yt_dlp_missing_message())
    result = subprocess.run(cmd, check=True, capture_output=True, text=True)
    return result.stdout

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code accepts a cookies file path and browser-cookie extraction option, then uses them for outbound requests to YouTube. While the script's purpose involves fetching transcripts, there is no explicit warning in code comments, help text, or user-facing output that browser/session cookies may be accessed and transmitted to a third-party service.

Content

No source excerpt is available for this finding.

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/transcribe_with_fallback.py (reported line 299)May include surrounding context.

python
]
    try:
        with_retries(
            lambda: subprocess.run(cmd, check=True, capture_output=True, text=True),
            retries=args.retry_count,
            delay_seconds=args.retry_delay_seconds,
        )

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/transcribe_with_fallback.py (reported line 331)May include surrounding context.

python
]
    try:
        with_retries(
            lambda: subprocess.run(cmd, check=True, capture_output=True, text=True),
            retries=args.retry_count,
            delay_seconds=args.retry_delay_seconds,
        )

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly states that the skill produces transcript files, JSON/CSV datasets, markdown notes, and reports, but it does not warn users that these artifacts will be written to local storage and may persist after execution. In a research workflow handling proprietary, personal, or sensitive video content, this can lead to unintentional data retention and broader exposure than the user expects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file describes generating transcripts from downloaded audio and producing transcript, JSON, CSV, and markdown files, but it does not explicitly warn the user that the workflow may download media and create multiple local artifacts. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors that could affect user data or system state.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

When a preferred language is provided, the code passes it directly to the local transcription model, which can constrain processing to that language. This is a locale/language policy concern because the file contains no natural-language justification or opt-in messaging beyond the raw parameter, and the behavior may override automatic language handling.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.