Back to skill

Security audit

Podcastfy Clawdbot Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to make podcasts from URLs, but it automatically installs changing third-party code and exposes the full environment to that code during execution.

Install only if you are comfortable with the skill downloading and executing current upstream Python packages and Playwright browser components at run time. Use a dedicated environment with only the needed Gemini key present, avoid confidential or authenticated URLs, and prefer pinned dependencies or a prebuilt isolated environment before production use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
scripts/podcastfy_generate.py:66
Finding

Unpinned Dependencies Are Automatically Downloaded and Upgraded at Runtime

Content
View full analysis

Vulnerability Details

File Location: scripts/podcastfy_generate.py, lines 66–72
Vulnerability Type: Supply-chain exposure through unpinned runtime dependencies
Risk Level: Medium

Vulnerable Code:

python
def ensure_deps() -> None:
    # Pin loosely; let pip resolve compatible versions.
    subprocess.run([str(PIP), "install", "-U", "podcastfy", "playwright"], check=True)

    # Podcastfy's website extractor may use Playwright. Ensure a browser is installed.
    try:
        subprocess.run([str(PY), "-m", "playwright", "install", "chromium"], check=True)
    except Exception as e:
        raise SystemExit(f"Failed to install Playwright Chromium: {e}")

Technical Analysis

The script installs or upgrades podcastfy and playwright without exact version constraints or package hashes whenever ensure_deps() runs. It also downloads a Chromium artifact selected by the dynamically installed Playwright version.

This means the effective code and browser binaries executed by the Skill can change after the Skill itself has been reviewed. The -U option further causes existing installations to be replaced by the newest versions available from the configured package index.

The downloaded dependencies subsequently execute in the podcast-generation process. That child process receives a copy of the complete environment:

python
env = os.environ.copy()

This environment includes the required GEMINI_API_KEY. Therefore, a compromised, malicious, or unexpectedly changed upstream release could access that credential and other inherited environment data. No direct compromise of the current named dependencies was established; the vulnerability is the unsafe dependency acquisition and execution model.

Attack Path

  1. An attacker compromises an upstream package release, its maintainer account, distribution infrastructure, or the package index used by the host.
  2. The victim invokes `s ...[truncated 1239 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin every direct and transitive dependency to reviewed versions in a lock file.
  2. Require cryptographic hashes during installation, for example with pip install --require-hashes -r requirements.txt.
  3. Remove -U from the normal execution path. Dependency updates should occur only during an explicit, reviewed maintenance process.
  4. Install dependencies during deployment or setup rather than each podcast-generation run.
  5. Pin the Playwright version and corresponding Chromium revision. Verify downloaded browser artifacts where supported.
  6. Use a trusted package index and restrict fallback to unapproved indexes or mirrors.
  7. Construct a minimal child-process environment instead of copying all of os.environ. Pass only variables required by Podcastfy and Gemini.
  8. Run the Skill in a restricted container or service account with limited filesystem access, constrained outbound networking, and no unrelated credentials.
  9. Add dependency vulnerability and integrity scanning to the release process, and review dependency changes before updating the lock file.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (20)

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · README.md (reported line 35)May include surrounding context.

Install ffmpeg (Ubuntu/Debian):

bash
sudo apt-get update && sudo apt-get install -y ffmpeg

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · README.md (reported line 138)May include surrounding context.

Install ffmpeg (Ubuntu/Debian):

bash
sudo apt-get update && sudo apt-get install -y ffmpeg

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/podcastfy_generate.py (reported line 53)May include surrounding context.

python
Install ffmpeg (Ubuntu/Debian):

```bash
sudo apt-get update && sudo apt-get install -y ffmpeg
```

---

Chaining Abuse

High
Category
Tool Misuse
Confidence
86% confidence
Finding

The chained privileged command combines update and install into a single shell line, which encourages one-shot execution with elevated privileges and less operator scrutiny. In practice, command chaining reduces opportunities to validate repository state, package trust, or execution intent before making persistent system changes.

Content

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

Ubuntu/Debian:

bash
sudo apt-get update && sudo apt-get install -y ffmpeg
  1. Provide a Gemini API key:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
91% confidence
Finding

Copying the entire environment into a child process is a genuine secret-exposure issue in this context. The child code imports third-party packages and processes untrusted remote content, so inheriting all environment variables may expose unrelated API keys, tokens, and credentials if any dependency logs, transmits, or mishandles them.

Content

Scanner excerpt · scripts/podcastfy_generate.py (reported line 210)May include surrounding context.

python
print(out)
'''

    env = os.environ.copy()
    env["_PODCASTFY_URLS"] = "\n".join(args.urls)
    env["_PODCASTFY_LONGFORM"] = "1" if args.longform else "0"
    env["_PODCASTFY_CONV_CFG"] = str(conv_cfg)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly states that URL-derived content is processed by external services (Gemini for script generation and Edge TTS for speech synthesis), but it does not clearly warn users that fetched page contents, summaries, or generated transcripts may leave the local environment and be sent to third-party providers. In a skill that ingests arbitrary URLs, this can lead to unintended disclosure of sensitive or internal content if users provide private links or authenticated resources.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 35)May include surrounding context.

Install ffmpeg (Ubuntu/Debian):

bash
sudo apt-get update && sudo apt-get install -y ffmpeg

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 138)May include surrounding context.

Install ffmpeg (Ubuntu/Debian):

bash
sudo apt-get update && sudo apt-get install -y ffmpeg

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises operational behavior that uses shell execution, environment variables, and file reads/writes, but it does not declare any explicit tool scope or permission boundaries. In an agent environment, this can lead to over-broad execution authority, making it easier for the skill to perform unintended local changes, package installation, or secret exposure if invoked in the wrong context.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger language is broad enough to match common summarization or content-conversion requests, which increases the chance the skill is invoked unexpectedly. Because the skill performs package setup, network retrieval from arbitrary URLs, and local file generation, accidental activation expands the attack surface and could cause unreviewed execution on untrusted content.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
88% confidence
Finding

The documentation instructs use of sudo for package installation, which normalizes privileged execution in the skill workflow. In agent-assisted or copy-paste scenarios, this can cause users or automation to run elevated system-modifying commands without sufficient review, increasing the risk of host compromise or unintended system changes.

Content

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

Ubuntu/Debian:

bash
sudo apt-get update && sudo apt-get install -y ffmpeg
  1. Provide a Gemini API key:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/podcastfy_generate.py (reported line 53)May include surrounding context.

python
if shutil.which("ffmpeg"):
        return
    raise SystemExit(
        "ffmpeg not found on PATH. Install it first (Ubuntu/Debian): sudo apt-get update && sudo apt-get install -y ffmpeg"
    )

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

python
if PY.exists() and PIP.exists():
        return

    subprocess.run(["python3", "-m", "venv", str(VENV_DIR)], check=True)
    subprocess.run([str(PIP), "install", "--upgrade", "pip"], check=True)

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

python
return

    subprocess.run(["python3", "-m", "venv", str(VENV_DIR)], check=True)
    subprocess.run([str(PIP), "install", "--upgrade", "pip"], check=True)


def ensure_deps() -> None:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The script installs podcastfy and playwright at runtime with loose, unpinned versions from the package index. In a skill context, this creates a real supply-chain risk: execution behavior depends on whatever package versions are available at run time, and a compromised package or dependency could lead to arbitrary code execution under the agent's privileges.

Content

Scanner excerpt · scripts/podcastfy_generate.py (reported line 67)May include surrounding context.

python
def ensure_deps() -> None:
    # Pin loosely; let pip resolve compatible versions.
    subprocess.run([str(PIP), "install", "-U", "podcastfy", "playwright"], check=True)

    # Podcastfy's website extractor may use Playwright. Ensure a browser is installed.
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

This runtime installation of Playwright Chromium downloads and installs executable browser components during skill execution. That expands the attack surface and creates supply-chain and integrity risks, especially in an automated agent environment where fetched binaries are executed without a separate trust review.

Content

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

python
# Podcastfy's website extractor may use Playwright. Ensure a browser is installed.
    try:
        subprocess.run([str(PY), "-m", "playwright", "install", "chromium"], check=True)
    except Exception as e:
        raise SystemExit(f"Failed to install Playwright Chromium: {e}")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The generated conversation config explicitly sets output_language: English, which forces a specific language for all users. This is a natural-language locale policy issue because the script provides no user-facing option to choose another language or opt in to English-only output.

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

python
# Duration sanity check.
    try:
        p = subprocess.run(
            [
                "ffprobe",
                "-hide_banner",

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

python
out_mp3_path.parent.mkdir(parents=True, exist_ok=True)

    subprocess.run(
        [
            str(EDGE_TTS),
            "-f",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
86% confidence
Finding

The subprocess launches inline Python code while passing a full copy of the parent environment, including secrets unrelated to this task. In an agent setting that processes untrusted URLs and third-party libraries, broad environment propagation increases blast radius if the child process or dependencies are compromised, because all inherited secrets become accessible.

Content

Scanner excerpt · scripts/podcastfy_generate.py (reported line 220)May include surrounding context.

python
if cfg_path.exists():
        env["_PODCASTFY_CFG"] = str(cfg_path)

    proc = subprocess.run([str(PY), "-c", code], env=env, text=True)
    if proc.returncode != 0:
        return proc.returncode

Static analysis

No suspicious patterns detected.