Back to skill

Security audit

Scientific Podcast Summary

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly a podcast summarizer, but it can fetch any user-supplied URL, send extracted content to a configurable LLM endpoint, and overwrite arbitrary writable output files.

Install only if you are comfortable with the skill fetching web pages, sending extracted content to OpenAI or the configured compatible API endpoint, and writing files where directed. Use only public podcast URLs from trusted domains, avoid private or internal URLs, keep OPENAI_BASE_URL pointed at a trusted provider, and choose output paths carefully because existing writable files can be overwritten.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:67
Finding

Unrestricted URL Fetching Enables SSRF and External Data Disclosure

Content
View full analysis
Optional[str]: """Get URL content""" default_headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" } if headers: default_headers.update(headers) try: resp = requests.get(url, headers=default_headers, timeout=30) resp.raise_for_status() return resp.text except Exception as e: log(f"getURLfail: {url} - {e}", "error") return None def call_llm(prompt: str) -> Optional[str]: """Call LLM API""" if not OPENAI_API_KEY: log("OPENAI_API_KEY environment variable not set", "error") return None try: import openai client = openai.OpenAI( api_key=OPENAI_API_KEY, base_url=OPENAI_BASE_URL, ) resp = client.chat.completions.create( model=DEFAULT_MODEL, messages=[ {"role": "system", "content": "You are a professional scientific content summary assistant."}, {"role": "user", "content": prompt}, ], temperature=0.3, ) return resp.choices[0].message.content ``` ```python # Get target URL target_url = args.url if not target_url: log(f"Getting latest {PODCAST_SOURCES[args.podcast]['name']} English...") if args.podcast == "huberman": target_url = get_latest_huberman_url() else: target_url = get_latest_nature_url() if not target_url: log("Unable to get podcast URL", "error") sys.exit(1) log(f"parse page: {target_url}") # Get page content html = fetch_url(target_url) if not html: sys.exit(1) # parse content if args.podcast == "huberman": ep ...[truncated 3037 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:450
Finding

User-Controlled Output Path Allows Arbitrary File Overwrite

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned and Ambiguous Third-Party Dependencies

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (12)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents executable Python code with environment variable access, network calls, and file output, but does not declare any explicit tool permissions or allowed-tools scope. That creates an authorization and review gap: an agent may invoke capabilities broader than the user expects, increasing the risk of data exfiltration via env access, unbounded outbound requests, or writing files outside intended locations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The activation guidance is broad enough that an agent could apply this skill to loosely related 'evidence insight' tasks rather than only podcast summarization. Overbroad triggers increase the chance of inappropriate invocation, which can lead to unnecessary external fetching, LLM processing of unintended content, and execution of the bundled script in contexts the user did not specifically authorize.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/main.py (reported line 22)May include surrounding context.

python
DEFAULT_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_BASE_URL = os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")

PODCAST_SOURCES = {
    "huberman": {

Ssd 1

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The prompt template embeds untrusted webpage content directly into the same instruction channel as the summarization request. Malicious page text can include prompt-injection content that attempts to override behavior, distort output, or induce the model to reveal or fabricate information, and the arbitrary URL support makes this more dangerous in practice.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The generic page parser enables summarization of arbitrary webpages, which exceeds the stated scope of summarizing specific scientific podcasts. In this context, unnecessary generality is risky because it makes it easier to feed attacker-controlled pages into the LLM pipeline and weakens any assumption that input comes only from trusted podcast publishers.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Fetched external content is passed straight into the LLM with no sanitization or trust separation at the point of use. Even if the model does not have tools here, prompt injection can still corrupt summaries, produce misleading structured output, or manipulate downstream consumers that trust the model response.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Extracted podcast or webpage content is sent to an external LLM provider without any user-facing disclosure, confirmation, or data handling notice. If users provide private, paywalled, or sensitive URLs, the tool may transmit that material off-box unexpectedly, creating privacy, compliance, and confidentiality risks.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises support for specific podcast sources, but the --url option allows fetching arbitrary user-supplied URLs and processing them as input. This broadens the trust boundary, enables server-side retrieval of attacker-controlled content, and increases exposure to prompt injection, unexpected data handling, and misuse beyond the declared purpose.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency 'bs4' is unpinned, which makes builds non-reproducible and allows future installs to pull in unexpected or vulnerable releases. While this file alone does not prove exploitation, lack of version pinning increases supply-chain risk and complicates vulnerability management.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
bs4
openai
requests

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

The 'openai' package is also unpinned, so installations may resolve to different versions over time, including releases with breaking changes or newly introduced security issues. This creates a supply-chain exposure rather than an immediate direct exploit in the manifest itself.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
bs4
openai
requests

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
100% confidence
Finding

The 'requests' dependency is unpinned, which is particularly risky because it is a network-facing library with a history of security advisories. Without pinning, the environment may install an affected or otherwise unreviewed version, increasing supply-chain and patch-management risk.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
bs4
openai
requests

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The manifest includes 'requests' without a version, and that package has multiple known advisories across releases. Because the version is not specified, it is impossible to verify whether deployment will use a safe release, leaving the skill exposed to known issues such as credential leakage or TLS/verification-related flaws depending on the resolved version.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.