Back to skill

Security audit

Slides/PPT generation and voice narration

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says for 2slides presentation generation, but its setup guidance exposes API keys and can run an unpinned MCP package, so users should review it before installing.

Install only if you are comfortable sending presentation text, document-derived content, and reference images to 2slides. Prefer the direct Python scripts or a pinned, reviewed MCP package; avoid putting API keys in URLs when a header or protected secret mechanism is available, and rotate any key that may have been logged or shared.

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

T08 · Insecure Dependencies

Warning
Location
references/mcp-integration.md:58
Finding

Unpinned NPM Package Is Downloaded and Executed Through npx

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/mcp-integration.md:28
Finding

API Credential Is Embedded in the MCP Endpoint Query String

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (35)

Tainted flow: 'headers' from os.environ.get (line 61, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/create_pdf_slides.py (reported line 85)May include surrounding context.

python
print("Generating custom-designed slides...", file=sys.stderr)
    print(f"(Timeout set to {timeout}s for {page} page(s))", file=sys.stderr)
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'headers' from os.environ.get (line 55, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/download_slides_pages_voices.py (reported line 68)May include surrounding context.

python
print(f"Requesting download for job: {job_id}...", file=sys.stderr)

    response = requests.post(url, headers=headers, json=payload, timeout=30)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'headers' from os.environ.get (line 77, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/generate_narration.py (reported line 97)May include surrounding context.

python
# Set reasonable timeout for narration generation
    timeout = 120

    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'headers' from os.environ.get (line 133, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/generate_slides.py (reported line 74)May include surrounding context.

python
timeout = 90 if mode == "sync" else 30

    print(f"Generating slides in {mode} mode...", file=sys.stderr)
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'headers' from os.environ.get (line 133, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/generate_slides.py (reported line 155)May include surrounding context.

python
timeout = 90 if mode == "sync" else 30

    print(f"Generating slides in {mode} mode...", file=sys.stderr)
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'headers' from os.environ.get (line 45, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

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

python
url = f"{API_BASE_URL}/jobs/{job_id}"

    print(f"Checking job status: {job_id}...", file=sys.stderr)
    response = requests.get(url, headers=headers)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'headers' from os.environ.get (line 47, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/search_themes.py (reported line 60)May include surrounding context.

python
url = f"{API_BASE_URL}/themes/search"

    print(f"Searching themes{f': {query}' if query else ''}...", file=sys.stderr)
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()

    result = response.json()

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The code is related to presentation generation and does use the 2slides API, so the broad domain is accurate. However, the declared description claims several capabilities not present in this code chunk: creating slides from reference images, summarizing documents into presentations, and supporting both synchronous and asynchronous generation modes. The actual script accepts only text content (--content) plus optional free-form design specs, and calls a single create-pdf-slides API endpoint. It does not process files/documents, images, or implement separate async workflows. Therefore the description overstates the implemented behavior enough to count as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose centers on creating presentations via 2slides, but this code chunk only downloads assets for an already existing generation job identified by job_id. Its primary purpose is export/retrieval of generated slide pages and voice files, not presentation creation. While related to the same product domain, the implemented behavior is materially different from the declared generation workflow.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description focuses on creating presentations/slides from content via the 2slides API. The actual code does not generate presentations at all; instead, its primary purpose is adding audio narration to already-generated slides. This is a materially different capability and workflow: it requires an existing completed job ID, invokes a narration-specific endpoint, and exposes voice/multi-speaker options that are not described in the skill declaration. Therefore the description does not accurately represent the code's behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This code chunk has a much narrower purpose than the declared description. It does interact with the same 2slides service and is loosely related through theme discovery, but its actual function is limited to searching available themes. There is no slide or deck generation, no document summarization, no image style matching, and no generation workflow at all. Theme selection support is only indirectly represented by theme lookup. Therefore the code does not accurately match the declared primary purpose of presentation generation.

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

python
def get_api_key() -> str:
    """Get API key from environment variable."""
    api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(

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

python
def get_api_key() -> str:
    """Get API key from environment variable."""
    api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(

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

python
def get_api_key() -> str:
    """Get API key from environment variable."""
    api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(

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

python
def get_api_key() -> str:
    """Get API key from environment variable."""
    api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(

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

python
def get_api_key() -> str:
    """Get API key from environment variable."""
    api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(

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

python
def get_api_key() -> str:
    """Get API key from environment variable."""
    api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
# 2slides Skills for Claude Code

AI-powered presentation generation using the [2slides API](https://2slides.com). This Claude Code skill enables you to create professional presentations from text content, match reference image styles, or summarize documents into slides.

## Important Links

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README encourages users to upload documents and presentation content to the external 2slides service but does not clearly warn that attached files, text, and image URLs may be transmitted to and processed by a third-party API. This creates a real privacy and data-handling risk because users may submit sensitive internal reports, research papers, or proprietary content without informed consent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs use of environment secrets and outbound network access but does not declare an explicit tool scope such as permissions or allowed-tools. That gap weakens least-privilege controls and makes it harder for the hosting agent to constrain secret access and external data transmission, especially since the skill sends user content to a third-party API.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger language is broad enough to activate on generic presentation-related requests, increasing the chance that sensitive text, documents, or image URLs are routed to this external service unintentionally. In an agent setting, unintended invocation can cause surprise data transfer, unnecessary API spend, and processing of content the user did not explicitly consent to send off-platform.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill repeatedly instructs sending user-provided content, documents, and reference image URLs to 2slides but does not provide a clear privacy warning or consent checkpoint. This is dangerous because users may provide confidential business, personal, or copyrighted material without realizing it will be transmitted to an external processor.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Embedding the API key directly in an MCP URL encourages credential exposure through logs, process listings, screenshots, browser history, copied config files, and telemetry systems. URL-based secrets are especially risky because many tools automatically record full request strings, turning a simple setup example into a durable credential leak path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The API reference instructs callers to send arbitrary user-provided content to a third-party slide-generation service but provides no warning about privacy, confidentiality, or data retention implications. In a skill that may be used on sensitive business documents or internal content, this omission can lead users or integrators to unknowingly exfiltrate proprietary or personal data to an external processor.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reference-image endpoint accepts image URLs or base64 image data and encourages submission of external or uploaded images without warning that those images are sent to a third-party service for style matching. Reference images often contain sensitive visuals, metadata, internal diagrams, or personal information, so omission of a privacy warning materially increases the risk of unintended disclosure.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.