Back to skill

Security audit

Slideshow Video

Security checks for vulnerabilities and agentic risk

Overview

This slideshow skill mostly matches its stated purpose, but it needs Review because it can steer generated videos toward a Clawlite.ai call-to-action and uses broad network, session, and file-write authority without enough safeguards.

Before installing, remove or override the Clawlite.ai CTA default, run only trusted project JSON files, prefer local images and audio, avoid sensitive prompts or private URLs, keep `OPENCLAW_BASE_URL` pinned to a trusted local endpoint, and run the pipeline in a constrained output directory.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:21
Finding

Mandatory Third-Party Promotional CTA Alters User-Requested Output

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_slides.py:96
Finding

Unrestricted Remote Image and Audio Fetching Enables SSRF

Content
View full analysis
bool: return value.startswith("http://") or value.startswith("https://") def cache_remote_image(url: str, cache_dir: Path) -> Path: parsed = urllib.parse.urlparse(url) suffix = Path(parsed.path).suffix or ".img" name = hashlib.sha256(url.encode("utf-8")).hexdigest()[:24] + suffix out = cache_dir / name if out.exists() and out.stat().st_size > 0: return out cache_dir.mkdir(parents=True, exist_ok=True) req = urllib.request.Request(url, headers={"User-Agent": "OpenClaw slideshow-video skill"}) with urllib.request.urlopen(req, timeout=60) as response, open(out, "wb") as f: f.write(response.read()) return out ``` Remote audio is passed directly to FFmpeg: ```python if args.audio: cmd.extend([ "-stream_loop", "-1", "-i", args.audio, "-filter_complex", f"[1:a]volume={args.audio_volume},atrim=duration={total_duration}[bgm]", "-map", "0:v:0", "-map", "[bgm]", ]) ``` ### Technical Analysis The project configuration controls `imageUrl`, URL-valued `imagePath`, and `audio.url`. The implementation only verifies that image URLs begin with `http://` or `https://`. It does not validate the destination hostname, resolved IP address, redirect chain, protocol security, response type, or response size. Consequently, the process can be induced to request: - Loopback services such as `127.0.0.1`. - Private network services. - Link-local endpoints, including cloud instance metadata services. - Attacker-controlled redirectors that ultimately resolve to internal addresses. The image downloader reads the complete ...[truncated 2028 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/resolve_images.py:148
Finding

OpenClaw Session Credential Can Be Disclosed to an Arbitrary Configured Endpoint

Content
View full analysis
str: return os.environ.get("OPENCLAW_BASE_URL", "http://127.0.0.1:3333").rstrip("/") def get_openclaw_session_key() -> Optional[str]: return os.environ.get("OPENCLAW_SESSION_KEY") or os.environ.get("OPENCLAW_SESSION") def call_openclaw_image_generate(prompt: str, model: str, size: Optional[str] = None, filename: Optional[str] = None) -> Optional[str]: session_key = get_openclaw_session_key() if not session_key: return None payload = { "tool": "image_generate", "arguments": { "action": "generate", "model": model, "prompt": prompt, }, } if size: payload["arguments"]["size"] = size if filename: payload["arguments"]["filename"] = filename req = urllib.request.Request( f"{get_openclaw_api_base()}/api/sessions/{urllib.parse.quote(session_key)}/tool-call", data=json.dumps(payload).encode("utf-8"), headers={ "Content-Type": "application/json", "Accept": "application/json", }, method="POST", ) with urllib.request.urlopen(req, timeout=180) as response: body = json.loads(response.read().decode("utf-8", errors="ignore")) ``` ### Technical Analysis The code reads a sensitive OpenClaw session credential from the environment and inserts it into the URL path. The request destination is independently controlled through `OPENCLAW_BASE_URL`, with no validation that the endpoint is loopback, trusted, or protected by TLS. If the environment variable is changed through deployment configuration, a wrapper process, a compromised shell profile, or another mechanism, the Skill sends the session key to that endpo ...[truncated 1826 chars]
Remediation
View remediation
``` 5. Disable redirects or revalidate the destination before following each redirect. 6. Redact authorization data and session identifiers from logs and exceptions. 7. Use a narrowly scoped, short-lived token dedicated to image-generation calls instead of a general session credential. 8. Document the trust requirements for environment variables and fail closed when endpoint validation fails. 9. Rotate any credential that may already have been sent to an untrusted endpoint or retained in URL logs. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_pipeline.py:32
Finding

Project-Controlled Paths Can Escape the Configured Output Directory

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (22)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
npm install

# Configure your OpenClaw environment
cp .env.example .env
# Add OPENAI_API_KEY, ELEVENLABS_API_KEY, etc.

# Generate a slideshow video from a blog post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/resolve_images.py`: resolve `imageQuery` values into usable remote image URLs

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README encourages ingestion of URLs, tweets, briefs, and transcripts, which can contain sensitive or proprietary data, yet it gives no warning that this content may be transmitted to external providers for fetching, image generation, narration, or rendering. In an agent-skill context, that omission increases the chance users unknowingly expose confidential material to third-party services.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes a slideshow generator driven by image sources and structured copy, but the README expands the skill into a content-ingestion pipeline that accepts blog post URLs, tweet threads, and other arbitrary content sources. That is a broader behavior domain than the manifest's stated scope and changes the skill from asset assembly into source-content ingestion and transformation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest focuses on generating slideshows, captions, voice sync, and MP4 exports. The README describes additional behavior around Schema.org metadata generation, hosting-page transcript embedding, crawler indexing support, and cross-linking for discovery, which are publishing/SEO capabilities outside the manifest's stated asset-generation scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The setup instructions tell users to populate API keys and use external AI services, but they omit basic guidance on secret handling and third-party processing. This can lead to accidental credential exposure through committed .env files, shared environments, logs, or misunderstanding about where user data is sent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill describes capabilities that involve shell execution, file read/write, environment access, and network retrieval, but it does not declare an explicit tool scope or permission boundary. That makes it easier for an agent or operator to invoke the skill with broader-than-necessary privileges, increasing the chance of unintended command execution, filesystem modification, or data exposure.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 26)May include surrounding context.

  1. Prepare 5 to 8 local images, GPT Image 2 outputs, remote image URLs, or image queries for one slideshow.
  2. Copy references/pipeline.example.json to a working JSON file and replace the image sources and copy.
  3. For production TikTok slideshows, generate or collect your GPT Image 2 scenes first, then write one voice line per slide for ElevenLabs.
  4. Run the full pipeline:
bash

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill instructs users to download remote images and even resolve image queries into remote URLs, but it does not clearly warn that image sources, queries, IP address, and possibly project metadata may be transmitted to third parties and cached locally. This can leak sensitive prompts, campaign plans, or internal content sourcing behavior, especially in enterprise or confidential workflows.

Content

No source excerpt is available for this finding.

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 · references/workflow.md (reported line 17)May include surrounding context.

md
Use this path for TikTok or Shorts posts where voice timing must match the slide timing.

1. Write one spoken sentence per slide.
2. Generate one ordered audio file per sentence, such as `line_01.mp3`, `line_02.mp3`.
3. Keep on-screen text shorter than the sentence. Use captions as emphasis, not full transcript.
4. Generate slides in the same order.

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

python
def run(cmd):
    return subprocess.run(cmd, check=False)


def main():

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script explicitly allows --audio to be a remote URL and passes it to ffmpeg unchanged. That expands a local media-processing tool into one that can make outbound network requests, creating SSRF-style exposure, unexpected data egress, and risk from ffmpeg parsing untrusted remote content.

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

python
def ffprobe_duration(path: Path) -> float:
    out = subprocess.check_output([
        'ffprobe', '-v', 'error', '-show_entries', 'format=duration',
        '-of', 'default=noprint_wrappers=1:nokey=1', str(path)
    ], text=True).strip()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script unconditionally recreates predictable intermediate files in the output directory, including concat manifests, merged audio, and sync metadata, before the user opts into overwrite behavior for the final export. In shared or automation-heavy environments, this can destroy prior outputs or overwrite attacker-planted symlink targets, causing data loss or unintended file modification.

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

python
fv.write(f'duration {duration:.3f}\n')
        fv.write(f"file '{slides[-1].as_posix()}'\n")

    subprocess.run([
        'ffmpeg', '-y', '-hide_banner', '-loglevel', 'error',
        '-f', 'concat', '-safe', '0', '-i', str(audio_concat),
        '-c:a', 'libmp3lame', '-q:a', '2', str(merged_audio)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sends user-provided image queries to external services such as Pinterest, Unsplash, and potentially an image-generation backend without any consent, warning, or privacy boundary. In this skill’s context, queries may encode campaign plans, customer data, or sensitive prompts, so silent third-party disclosure is a real privacy and data-handling risk even if it is part of the intended functionality.

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

python
def run(cmd):
    subprocess.run(cmd, check=True)


def main():

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

python
def run(cmd):
    subprocess.run(cmd, check=True)


def main():

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

python
def run(cmd):
    subprocess.run(cmd, check=True)


def main():

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The tech stack explicitly includes web_fetch, pdf, summarize, and sessions_spawn, which indicates a broader orchestration and content acquisition workflow than simply generating slideshow assets and MP4s from supplied images/copy. While related to content production, these capabilities materially expand the skill's operational scope beyond the manifest wording.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

ffmpeg is invoked with an attacker-controlled secondary input that may be a remote URL, causing the host running the skill to retrieve and parse arbitrary remote media. In an agent or automation environment, this is more dangerous because it can be abused for internal network access, metadata-service probing, or denial of service through oversized or malformed media.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

When --output is provided, the script writes a file to disk, but the code gives no explicit disclosure beyond the argument name that it will create or overwrite a file. This is a file-write operation in a code file and lacks a clear warning, confirmation, or explanatory comment.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.