Back to skill

Security audit

HTML Slides for OpenClaw

Security checks for vulnerabilities and agentic risk

Overview

This slide-making skill is mostly coherent, but its optional export and publishing tools create real review-worthy risks around public sharing, unpinned package execution, and local file exposure.

Review before installing. The core local slide generation looks purpose-aligned, but avoid running the deployment or PDF export scripts on sensitive presentations unless you accept public Vercel publishing, third-party package execution, and the temporary export-server risk. Prefer local-only use, pinned dependencies, and explicit confirmation before any upload or export.

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
scripts/export-pdf.sh:159
Finding

Directory Traversal in Network-Accessible PDF Export Server

Content
View full analysis
{ // Decode URL-encoded characters (e.g., %20 → space) so filenames with spaces resolve correctly const decodedUrl = decodeURIComponent(req.url); let filePath = join(SERVE_DIR, decodedUrl === '/' ? HTML_FILE : decodedUrl); try { const content = readFileSync(filePath); const ext = extname(filePath).toLowerCase(); res.writeHead(200, { 'Content-Type': MIME_TYPES[ext] || 'application/octet-stream' }); res.end(content); } catch { res.writeHead(404); res.end('Not found'); } }); // Find a free port const port = await new Promise((resolve) => { server.listen(0, () => resolve(server.address().port)); }); ``` ### Technical Analysis The PDF exporter creates a temporary HTTP server to serve the directory containing the input presentation. The request URL is decoded and passed directly to `join(SERVE_DIR, ...)`, after which the resulting path is read with `readFileSync`. The implementation does not canonicalize the requested path and verify that it remains inside `SERVE_DIR`. Consequently, traversal components in an HTTP request can resolve to files outside the presentation directory. The server also uses `server.listen(0)` without explicitly binding to a loopback address. Depending on the Node.js runtime and host configuration, this can listen on unspecified network interfaces rather than only `127.0.0.1`. This expands the attack surface from local processes to network-adjacent clients that can discover or otherwise access the temporary port. Additionally, `decodeURIComponent(req.url)` is outside the `try` block. Invalid percent-encoding can throw an exception and terminate the exporter, creating a denial-of-service condition. ### Attack P ...[truncated 1398 chars]
Remediation
View remediation
{ resolve(server.address().port); }); ``` 2. Parse only the URL pathname, decode it inside a protected error handler, and reject malformed requests. 3. Canonicalize both the serving root and requested path with `resolve()`. 4. Verify that the canonical requested path equals the root or begins with the root followed by the platform path separator. 5. Reject NUL bytes, parent-directory traversal, and paths outside the serving root with HTTP 403. 6. Import and use `sep` from Node.js `path` to avoid unsafe string-prefix comparisons. Example hardened implementation: ```javascript import { resolve, sep, extname } from 'path'; const root = resolve(SERVE_DIR); const server = createServer((req, res) => { try { const pathname = new URL(req.url, 'http://127.0.0.1').pathname; const decodedPath = decodeURIComponent(pathname); if (decodedPath.includes('\0')) { res.writeHead(400); return res.end('Bad request'); } const requestedPath = decodedPath === '/' ? resolve(root, HTML_FILE) : resolve(root, `.${decodedPath}`); const insideRoot = requestedPath === root || requestedPath.startsWith(root + sep); if (!insideRoot) { res.writeHead(403); return res.end('Forbidden'); } const content = readFileSync(requestedPath); const ext = extname(requestedPath).toLowerCase(); res.writeHead(200, { 'Content-Type': MIME_TYPES[ext] || 'application/octet-stream' }); res.end(content); } catch { res.writeHead(404); res.end('Not found'); } }); server.listen(0, '127.0.0.1', () => { console.log(`Local server on port ${server.address().port}`); }); ``` 7. Add automated tests for plain and encoded traversal attempts, malformed percent-encoding, absolute paths, and valid files below the serving root. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/export-pdf.sh:354
Finding

Unpinned Third-Party Packages Are Downloaded and Executed at Runtime

Content
View full analysis
"$TEMP_DIR/package.json" << 'PKG' { "name": "slide-export", "private": true, "type": "module" } PKG # Install Playwright into the temp directory npm install playwright &>/dev/null || { err "Failed to install Playwright." err "Try running: npm install playwright" rm -rf "$TEMP_DIR" exit 1 } # Ensure Chromium browser binary is downloaded npx playwright install chromium 2>/dev/null || { err "Failed to install Chromium browser for Playwright." err "Try running manually: npx playwright install chromium" rm -rf "$TEMP_DIR" exit 1 } ``` From `scripts/deploy.sh`: ```bash # Check if vercel is available (either globally or via npx) if command -v vercel &>/dev/null; then VERCEL_CMD="vercel" ok "Vercel CLI found" elif npx --yes vercel --version &>/dev/null 2>&1; then VERCEL_CMD="npx --yes vercel" ok "Vercel CLI available via npx" else info "Installing Vercel CLI..." npm install -g vercel VERCEL_CMD="vercel" ok "Vercel CLI installed" fi ``` Related installation guidance also uses unpinned dependencies: ```text pip install python-pptx pip install Pillow npm install playwright ``` ### Technical Analysis The scripts download and execute the current registry versions of Playwright and the Vercel CLI without: - Exact version constraints - A committed lockfile - Integrity verification - Package provenance validation - A reviewed dependency snapshot - Restrictions on package lifecycle scripts `npx --yes vercel` can automatically retrieve and execute the package when a local or global copy is unavailable. `npm install playwright` resolves the current package ...[truncated 2033 chars]
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is described as creating HTML slides, but it also includes public deployment to Vercel, login steps, and dependency execution that materially expand its capabilities. This mismatch is dangerous because users may consent to local document generation without realizing the skill can publish content externally or invoke networked tooling.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill is described as creating HTML slides, but it also includes public deployment to Vercel, login steps, and dependency execution that materially expand its capabilities. This mismatch is dangerous because users may consent to local document generation without realizing the skill can publish content externally or invoke networked tooling.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bash scripts/export-pdf.sh <path-to-html> [output.pdf]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bash scripts/export-pdf.sh <path-to-html> [output.pdf]

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · html-template.md (reported line 15)May include surrounding context.

md
<meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Presentation Title</title>

    <!-- Fonts: use Fontshare or Google Fonts — never system fonts -->
    <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=...">

    <style>

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/deploy.sh (reported line 149)May include surrounding context.

sh
echo ""
    $VERCEL_CMD login || {
        err "Login failed. Please run 'vercel login' manually and try again."
        [[ "$CLEANUP_TEMP" == "true" ]] && rm -rf "$DEPLOY_DIR"
        exit 1
    }
    echo ""

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/deploy.sh (reported line 191)May include surrounding context.

sh
echo ""
    $VERCEL_CMD login || {
        err "Login failed. Please run 'vercel login' manually and try again."
        [[ "$CLEANUP_TEMP" == "true" ]] && rm -rf "$DEPLOY_DIR"
        exit 1
    }
    echo ""

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file defines the skill persona and interaction style entirely in Chinese, including direct instructions for how the assistant should address the user. There is no indication that language choice is optional or user-selectable, which can violate language/locale policy when a specific language is imposed by default.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documented trigger phrases are very broad, including common requests like '帮我做个 PPT' and '做演示', which can easily occur in normal conversation and unintentionally activate the skill. In an agent environment, overbroad activation increases the chance of the skill taking over a task flow and steering the user toward file generation, browser opening, deployment, or export actions without explicit opt-in for this specific skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README describes automatically opening a browser preview and optionally deploying to Vercel or exporting PDF, but it does not clearly warn that these are system-impacting actions or state that they require explicit user confirmation. In practice, this normalizes actions that may launch applications, invoke external services, or create distributable artifacts, increasing the risk of unintended execution in an agent context.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill instructs the agent to generate and save HTML files locally, but it does not declare any explicit tool scope such as file-write permissions or allowed tools. In an agent environment, undeclared write capability weakens policy enforcement and makes it harder to constrain where files are created or modified.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description lists activation phrases such as “做幻灯片 / 做 PPT / 做演示 / 做 slides”, including especially “做演示”, which is broad enough to match ordinary conversation rather than a narrowly scoped skill invocation. The file does not provide exclusion conditions or negative examples to clarify when the skill should not activate.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The skill metadata and operational instructions are entirely written in Chinese and present the workflow as Chinese-language by default, without offering a language choice or documenting a justified locale restriction. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Including Vercel deployment in the skill expands it from local content creation into external publication, which can expose sensitive slide contents, notes, or embedded assets to the public internet. In this context, the danger is elevated because the deployment path sits in an optional 'sharing' phase but is still embedded in the same skill flow, increasing the chance of accidental publication.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The deployment section lacks a strong user-facing warning that publishing to Vercel may make the slide deck accessible online. Without explicit risk disclosure, users may unknowingly expose confidential business, personal, or internal presentation content.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

Using npx vercel without pinning a version allows whatever package version is currently resolved to run at execution time. That creates supply-chain risk, because a compromised or breaking upstream release could execute unreviewed code in the user's environment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

A second unpinned npx vercel invocation repeats the same supply-chain exposure during login or deployment. Re-resolving an unpinned package at runtime increases the chance of executing unexpected code or behavior changes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stated purpose is to generate HTML presentations from user requirements or PPT files. Exporting via Node.js/Playwright shell commands is an additional document-processing capability that is not justified by the manifest's narrow creation/conversion description.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The entire skill file is written as normative instructions in Chinese and does not indicate that users may choose another language or locale. Under the policy criteria, forcing a specific language without user opt-in is a natural-language policy violation unless the constraint is explicitly justified.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The template instructs generated presentations to load remote fonts from Fontshare or Google Fonts, causing the viewer's browser to make network requests to third parties when the local HTML file is opened. That leaks metadata such as IP address, user agent, timing, and potentially referrer/context, which is especially risky for offline/local presentations that users may assume are self-contained.

Content

Scanner excerpt · html-template.md (reported line 16)May include surrounding context.

md
<title>Presentation Title</title>

    <!-- Fonts: use Fontshare or Google Fonts — never system fonts -->
    <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=...">

    <style>
        /* ===========================================

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The template explicitly calls for auto-save to localStorage and export/save functionality, but provides no requirement for clear user notice, consent, retention controls, or scope limits. In a slide-generation skill that may handle sensitive business or personal presentation content, silent persistence can leave confidential data stored in the browser or trigger unintended file writes/exports.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This skill is described as creating HTML slide decks, but the script additionally publishes content to a permanent public Vercel URL. That scope expansion is dangerous because slide decks often contain internal business plans, personal data, or draft material, and users may not expect automatic public hosting from a content-generation skill.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The script executes npx --yes vercel without pinning an exact package version, so it may fetch and run whatever version is current at execution time. That creates a supply-chain risk: a compromised upstream package, typo-squatted dependency path, or breaking CLI change could lead to arbitrary code execution on the user's machine during deployment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script installs third-party tooling and performs remote hosting operations, which go beyond local slide creation and introduce external trust dependencies. This increases risk because it modifies the user's environment and transmits generated content to an outside service, all within a skill whose primary purpose appears to be document generation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script may auto-install the Vercel CLI and later upload content to Vercel without an upfront, explicit warning that it will change the local system and send files to an external provider. For a slide-making skill, that lack of informed consent is risky because users may expose sensitive presentations or unintentionally approve software installation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.