Back to skill

Security audit

Demo Precacher

Security checks for vulnerabilities and agentic risk

Overview

This skill does useful demo precaching work, but its actual script is narrower and more sensitive than the description suggests, including external AI calls and persistent storage of child-associated demo content.

Review this before installing if you will use real names, children’s content, customer data, or production API credentials. Treat it as a narrow demo-seeding script, not a complete demo coverage verifier, and configure only test credentials plus a disposable Turso database unless retention and deletion controls are added.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Tainted flow: 'HEADERS_TURSO' from os.environ (line 12, credential/environment) → httpx.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/precache_demo.py (reported line 16)May include surrounding context.

python
def turso_exec(sql, params=None):
    body = {"statements": [{"q": sql, "params": params or []}]}
    r = httpx.post(TURSO_URL, headers=HEADERS_TURSO, json=body, timeout=30)
    return r.json()

def generate_story(child_name, language, prompt):

Tainted flow: 'ELEVENLABS_API_KEY' from os.environ (line 7, credential/environment) → httpx.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/precache_demo.py (reported line 39)May include surrounding context.

python
def generate_audio(text, voice_id="FGY2WhTYpPnrIDTdsKH5"):
    """Generate TTS audio, return base64 mp3"""
    r = httpx.post(
        f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
        headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
        json={"text": text, "model_id": "eleven_multilingual_v2",

Tainted flow: 'ELEVENLABS_API_KEY' from os.environ (line 7, credential/environment) → httpx.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/precache_demo.py (reported line 53)May include surrounding context.

python
def generate_sfx(prompt, duration=5.0):
    """Generate SFX, return base64 mp3"""
    r = httpx.post(
        "https://api.elevenlabs.io/v1/sound-generation",
        headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
        json={"text": prompt, "duration_seconds": duration},

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented behavior promises broad precaching, playback verification, and coverage reporting, but the described implementation appears to cache content into a database and call specific third-party generation services without actually performing the advertised validation steps. This mismatch is dangerous because users may trust the skill for demo safety and data-handling expectations while it performs different external writes and API interactions, potentially exposing content or causing operational failures.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares outbound network access and use of sensitive environment variables but does not declare an explicit tool scope such as permissions or allowed-tools. This creates an authorization and review gap: operators may not realize the skill can access secrets and make external API calls, increasing the chance of unintended data exposure or misuse during execution.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file-level documentation claims the demo story is pre-cached with both audio narrations and images stored in Turso. In practice, generate_image is defined but never called, and only story and audio_cache are inserted into the database.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script sends child-related prompts and generated story content to third-party AI providers without any consent check, minimization, or visible disclosure in code flow. In a demo-precache context, this increases privacy risk because operators may preload real or sensitive child-associated content into external services and then persist resulting content in the database.

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

python
def generate_audio(text, voice_id="FGY2WhTYpPnrIDTdsKH5"):
    """Generate TTS audio, return base64 mp3"""
    r = httpx.post(
        f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
        headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
        json={"text": text, "model_id": "eleven_multilingual_v2",
              "voice_settings": {"stability": 0.6, "similarity_boost": 0.8}},

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

python
def generate_audio(text, voice_id="FGY2WhTYpPnrIDTdsKH5"):
    """Generate TTS audio, return base64 mp3"""
    r = httpx.post(
        f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
        headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
        json={"text": text, "model_id": "eleven_multilingual_v2",
              "voice_settings": {"stability": 0.6, "similarity_boost": 0.8}},

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/precache_demo.py (reported line 53)May include surrounding context.

python
def generate_sfx(prompt, duration=5.0):
    """Generate SFX, return base64 mp3"""
    r = httpx.post(
        "https://api.elevenlabs.io/v1/sound-generation",
        headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
        json={"text": prompt, "duration_seconds": duration},

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes a broad precaching workflow that should hit every API endpoint in advance, verify playback, and report coverage gaps before demos. This script instead generates a hard-coded story, creates media, and inserts it into Turso; it contains no endpoint enumeration, playback verification, or coverage analysis/reporting.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The manifest focuses on pre-generating demo content and exercising demo APIs, but does not mention credential harvesting or environment access as part of scope. While external API use may be expected, directly pulling several secrets from environment variables is an extra capability not stated in the skill description.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The system prompt explicitly instructs the model to "Write in {lang_name}", which imposes a locale/language choice in generated output. In this file, the language is hardcoded by demo data rather than selected interactively or presented as an explicit opt-in choice.

Content

No source excerpt is available for this finding.