Back to skill

Security audit

Fitness Recipes AI

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its video-generation purpose, but it ships a hard-coded ElevenLabs credential and has under-scoped third-party/API behavior users should review before installing.

Review this skill before installing. Use isolated credentials with spending limits, rotate the exposed ElevenLabs key if you own it, do not rely on --test to prevent live API calls, and only enable any TikTok/Postiz posting after confirming there is an explicit approval step. Run it in a virtual environment and expect content to be sent to external media-generation services.

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)

T09 · Insecure Skill Coding Practices

Error
Location
create_videos.py:23
Finding

Hard-Coded ElevenLabs API Credential

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:32
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (31)

Tainted flow: 'headers' from os.getenv (line 46, 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 · elevenlabs_client.py (reported line 64)May include surrounding context.

python
print(f"🎤 Generating voiceover ({len(text)} chars)...")
    
    try:
        response = requests.post(
            f"{ELEVENLABS_URL}/{voice_id}",
            json=payload,
            headers=headers

Tainted flow: 'headers' from os.getenv (line 125, 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 · shotstack_client.py (reported line 134)May include surrounding context.

python
try:
        # Submit render job
        response = requests.post(
            f"{SHOTSTACK_URL}/render",
            json=timeline,
            headers=headers

Tainted flow: 'headers' from os.getenv (line 125, 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 · shotstack_client.py (reported line 147)May include surrounding context.

python
# Poll for completion
        while True:
            status_response = requests.get(
                f"{SHOTSTACK_URL}/render/{render_id}",
                headers=headers
            )

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A live-looking ElevenLabs API key is hardcoded directly in source code, exposing a reusable credential to anyone with file access or repository visibility. This can lead to unauthorized API usage, billing abuse, account compromise, and downstream exposure if the same secret handling practice is used elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The listing advertises automatic posting to TikTok but does not disclose that the skill can perform actions on a user's social media account or describe the privacy and account-security implications. This can mislead users about the level of access required, increase the chance of overbroad authorization, and cause unexpected publication of content from a connected account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill description states that it generates content with fal.ai, ElevenLabs, and Shotstack and can post to TikTok via Postiz, but it does not prominently warn users that recipe data, prompts, media, and possibly account-linked posting actions will be sent to third-party services. This can lead to users invoking the skill without understanding external data disclosure or automated social-media actions, increasing privacy, compliance, and reputational risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

The ffmpeg subprocess is invoked with unescaped text derived from food_name inside a filter expression, which can break ffmpeg parsing or enable unexpected behavior if that value later becomes user-controlled. The broad bare except also suppresses all errors, making misuse or failures invisible and reducing detectability of abuse.

Content

Scanner excerpt · create_videos.py (reported line 66)May include surrounding context.

python
]
    
    try:
        subprocess.run(cmd, capture_output=True, timeout=10)
    except:
        pass

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This code performs external transmission to ElevenLabs, sending script text and authentication data over the network. External transmission is expected for TTS functionality, but in a skill context it is still security-relevant because content leaves the local environment and may expose sensitive information.

Content

Scanner excerpt · create_videos.py (reported line 84)May include surrounding context.

python
"xi-api-key": ELEVENLABS_API_KEY
    }
    
    response = requests.post(
        f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
        json={
            "text": script[:2000],

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script sends generated text content to a third-party TTS provider without any user notice, consent flow, or data classification controls. If the script content later contains sensitive, proprietary, or personal data, this causes unintended external disclosure.

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 · create_videos.py (reported line 123)May include surrounding context.

python
str(video_path)
    ]
    
    result = subprocess.run(cmd, capture_output=True, timeout=120)
    
    if result.returncode != 0:
        log(f"   ⚠️ Video failed: {result.stderr[:100]}")

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · daily_batch.py (reported line 30)May include surrounding context.

python
print("="*60)
    print("🏋️ DAILY FITNESS RECIPE GENERATION")
    print("="*60)
    print(f"📅 Date: {__import__('datetime').datetime.now().strftime('%Y-%m-%d')}")
    print(f"🎬 Videos: {VIDEOS_PER_DAY}")
    print("="*60)

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 · create_videos.py (reported line 85)May include surrounding context.

python
from pathlib import Path

ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY", "")
ELEVENLABS_URL = "https://api.elevenlabs.io/v1/text-to-speech"


# Voice IDs for fitness content (energetic male voice)

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 · elevenlabs_client.py (reported line 11)May include surrounding context.

python
from pathlib import Path

ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY", "")
ELEVENLABS_URL = "https://api.elevenlabs.io/v1/text-to-speech"


# Voice IDs for fitness content (energetic male voice)

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · elevenlabs_client.py (reported line 64)May include surrounding context.

python
print(f"🎤 Generating voiceover ({len(text)} chars)...")
    
    try:
        response = requests.post(
            f"{ELEVENLABS_URL}/{voice_id}",
            json=payload,
            headers=headers

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

No manifest is available, so there is no declared purpose that would justify accessing environment-based credentials. The code directly reads FAL_API_KEY from the process environment, which is a privileged capability beyond simple local image formatting or placeholder generation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The function transmits user-provided prompt data to an external third-party service, which is a real data-exposure risk if prompts contain sensitive or proprietary information. In this skill context, external transmission is expected for image generation, but the code does not document the network transfer, set timeouts, or constrain follow-on downloads from returned URLs, making the behavior less transparent and somewhat riskier.

Content

Scanner excerpt · fal_client.py (reported line 44)May include surrounding context.

python
print(f"🎨 Generating: {prompt}")
    
    try:
        response = requests.post(FAL_API_URL, json=payload, headers=headers)
        response.raise_for_status()
        data = response.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · generate_videos.py (reported line 54)May include surrounding context.

python
"""Generate food image using fal.ai"""
    print(f"🎨 Generating image: {prompt}")
    # TODO: Implement fal.ai API call
    # response = requests.post(
    #     "https://fal.run/fal-ai/flux",
    #     headers={"Authorization": f"Key {CONFIG['api_keys']['fal_ai']}"},
    #     json={"prompt": prompt}

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The CLI exposes a --test flag that implies safe placeholder behavior, but the code never uses args.test and always executes the live generation pipeline. This can mislead operators into triggering real API calls, costs, external data transfers, or side effects when they expected a non-destructive test run.

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 · shotstack_client.py (reported line 12)May include surrounding context.

python
from pathlib import Path

SHOTSTACK_API_KEY = os.getenv("SHOTSTACK_API_KEY", "")
SHOTSTACK_URL = "https://api.shotstack.io/v1"


def create_video_timeline(

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · shotstack_client.py (reported line 134)May include surrounding context.

python
try:
        # Submit render job
        response = requests.post(
            f"{SHOTSTACK_URL}/render",
            json=timeline,
            headers=headers

Tainted flow: 'render_id' from requests.post (line 142, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · shotstack_client.py (reported line 147)May include surrounding context.

python
# Poll for completion
        while True:
            status_response = requests.get(
                f"{SHOTSTACK_URL}/render/{render_id}",
                headers=headers
            )

Tainted flow: 'video_url' from requests.get (line 155, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
91% confidence
Finding

The code downloads a URL taken directly from a prior API response without validating the hostname, scheme, or content type. If the upstream service, API response, or network path were compromised, this could enable server-side request forgery or retrieval of unexpected internal or malicious content, which is then written to disk.

Content

Scanner excerpt · shotstack_client.py (reported line 164)May include surrounding context.

python
output_dir.mkdir(parents=True, exist_ok=True)
                    output_path = str(output_dir / f"video_{render_id}.mp4")
                
                video_response = requests.get(video_url)
                with open(output_path, "wb") as f:
                    f.write(video_response.content)

Tainted flow: 'output_path' from requests.post (line 162, network input) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · shotstack_client.py (reported line 165)May include surrounding context.

python
output_path = str(output_dir / f"video_{render_id}.mp4")
                
                video_response = requests.get(video_url)
                with open(output_path, "wb") as f:
                    f.write(video_response.content)
                
                print(f"💾 Saved: {output_path}")

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This manifest declares sensitive environment variables required by the skill, including multiple API keys, but the visible description does not warn users that they must provide credentials or that external services will be used. For manifest/markdown-facing skill metadata, the lack of disclosure can leave users unaware of privacy and account-impact implications.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring states the tool uses 'Free food images from online sources'. In practice, get_food_image does not fetch online images; it creates a local placeholder image with ffmpeg and even comments 'For now, use a colored placeholder', which contradicts the documented behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.