Back to skill

Security audit

openclaw-visual

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its image-generation purpose, but it handles private logs and chats with an unsafe browser-rendering path that could expose sensitive content or local network resources.

Install only if you are comfortable giving the skill access to the specific journals or chat logs you ask it to visualize. Use it in an isolated environment with no sensitive local network access, avoid rendering untrusted HTML or attacker-provided image URLs, preview and redact outputs before sharing, and update or pin the browser-rendering dependencies before routine use.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate-image.js:116
Finding

Unescaped Template Variables Permit Active HTML and Script Injection

Content
View full analysis
{ return data[key] !== undefined ? data[key] : ''; }); return result; } // Build full HTML document function buildHTML(bodyContent, css) { return ` ${css} body { margin: 0; } ${bodyContent} `; } ``` The resulting document is loaded into Chromium without disabling scripts: ```javascript await page.setContent(html, { waitUntil: 'networkidle' }); ``` Representative template sinks include: ```html
{{CONTENT}}
``` ```html
{{REFLECTIONS_CONTENT}}
``` ### Technical Analysis The custom Mustache-style renderer inserts every variable directly into the HTML document without context-sensitive encoding. Consequently, values intended to represent plain text can terminate their surrounding HTML context and introduce arbitrary markup. Inputs can originate from direct user content, journal files, or chat-session records. An attacker who can influence any rendered value can supply payloads containing elements such as `
Remediation
View remediation
`, `"`, and `'`. 2. Implement context-specific encoding for values inserted into text, attributes, URLs, and CSS classes. 3. Introduce a separate explicit syntax or field type for trusted rich HTML. 4. Sanitize permitted rich HTML with a maintained allowlist sanitizer. Remove scripts, event-handler attributes, iframes, objects, embeds, unsafe SVG, dangerous URL schemes, and external resource references. 5. Disable JavaScript in the rendering page where possible: ```javascript await page.setJavaScriptEnabled(false); ``` 6. Add request interception and reject every network request except explicitly approved local resources. 7. Apply a restrictive Content Security Policy, for example by denying scripts, frames, objects, and network connections. 8. Validate input length and structure before rendering to reduce denial-of-service risks. 9. Add regression tests using payloads in every template field, including nested arrays and rich-content fields. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
assets/templates/article-long.html:7
Finding

Unrestricted Image URLs Allow Server-Side Request Forgery Through Chromium

Content
View full analysis
Cover {{/IMAGE_URL}} ``` The same pattern appears in the moment-card template: ```html {{#IMAGE_URL}}
moment
{{/IMAGE_URL}} ``` Chromium then loads the generated document and waits for network activity: ```javascript await page.setContent(html, { waitUntil: 'networkidle' }); ``` ### Technical Analysis `IMAGE_URL` is inserted directly into an `` attribute without URL parsing, scheme restrictions, hostname allowlisting, IP-range filtering, redirect validation, or request interception. Although the documentation states that images should use publicly accessible URLs, this is not enforced by the implementation. Chromium may therefore attempt to retrieve attacker-selected resources using the network privileges of the renderer host. Potential targets include: - Loopback services such as `127.0.0.1` or `localhost`. - Private network ranges. - Link-local services. - Cloud instance metadata endpoints. - Internal hostnames available through the renderer's DNS configuration. - Attacker-controlled endpoints used for tracking or network reconnaissance. Because the template renderer also fails to escape attribute values, an attacker is not necessarily limited to a syntactically valid image URL. Nevertheless, SSRF remains independently reachable using an ordinary URL in the documented `IMAGE_URL` field. ### Attack Path 1. An attacker supplies an `IMAGE_URL` pointing to an internal or privileged network location. 2. The URL is placed into the article-long or moment-car ...[truncated 1415 chars]
Remediation
View remediation
{ const url = new URL(route.request().url()); if (url.protocol === 'data:') { return route.continue(); } return route.abort(); }); ``` 11. Run the renderer in a network-isolated environment as defense in depth. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate-image.js:153
Finding

Chromium Rendering Is Performed With the Browser Sandbox Disabled

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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (28)

Known Vulnerable Dependency: basic-ftp==5.1.0 — 4 advisory(ies): CVE-2026-27699 (Basic FTP has Path Traversal Vulnerability in its downloadToDir() method); GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

Critical
Category
Supply Chain
Confidence
94% confidence
Finding

The lockfile includes basic-ftp 5.1.0 transitively via browser/proxy tooling, and the cited advisories indicate real defects in FTP command handling, path traversal, and DoS behavior. In this skill’s context, the package is not a declared top-level dependency and is likely only reachable through Puppeteer’s download/proxy support, so exploitability is limited unless the runtime interacts with attacker-controlled FTP/PAC resources.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: handlebars==4.7.8 — 8 advisory(ies): CVE-2026-33916 (Handlebars.js has Prototype Pollution Leading to XSS through Partial Template In); CVE-2026-33937 (Handlebars.js has JavaScript Injection via AST Type Confusion); CVE-2026-33938 (Handlebars.js has JavaScript Injection via AST Type Confusion by tampering @part) +5 more

Critical
Category
Supply Chain
Confidence
98% confidence
Finding

handlebars 4.7.8 is directly pulled in by node-html-to-image and has multiple severe advisories including prototype pollution and template/code injection classes. This is especially relevant for a skill that converts user-provided logs, chats, and messages into HTML/image output, because if untrusted content is incorporated into templates or helpers unsafely, it can enable XSS-like script execution inside the headless browser or template-compilation abuse.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
96% confidence
Finding

extract-zip 2.0.1 is present and has advisories for symlink-based arbitrary file write/path traversal during archive extraction. Here it is transitive under Puppeteer browser download tooling, so the main risk is during browser/archive installation or update flows rather than normal image rendering, but a compromised or attacker-influenced archive source could still lead to filesystem overwrite.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
83% confidence
Finding

js-yaml 4.1.1 has real CPU-consumption/DoS advisories around malicious YAML structures. In this package-lock it appears under cosmiconfig in Puppeteer tooling, so the risk mainly materializes if the environment loads attacker-controlled YAML config files during startup or browser configuration, which is plausible but not central to the stated skill behavior.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
88% confidence
Finding

ws 8.19.0 is included through Puppeteer-core and has advisories for memory disclosure and memory-exhaustion DoS. Because this skill relies on headless browser tooling, WebSocket transport is part of the control channel to the browser; while typically local, exposure increases if the browser debugging endpoint or related channels are reachable by other processes or hostile network actors.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill describes reading PhoenixClaw journal files and sending generated images without warning that personal journal entries may contain highly sensitive data. Because the output is designed for sharing in chat platforms, this increases the risk of accidental exposure of private reflections, names, locations, or other personal details.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill states it will scan today's session records and transform chat history into a shareable image, but it does not require explicit user confirmation or warn that sensitive conversation content may be included. This can lead to unintended disclosure of personal, confidential, or regulated information when the generated image is sent or shared.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The skill instructs users to run npx playwright without pinning a specific version, which can pull whatever package version is current at execution time. This creates supply-chain and reproducibility risk: a compromised or breaking upstream release could be installed and executed in the local environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-visible strings such as "总结", "心情趋势", and "能量分布" are hard-coded in Chinese in the template. Because the file does not expose a localization mechanism or indicate that the skill is limited to a Chinese-language audience, it appears to enforce a specific locale without user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documented workflow reads markdown journal files from ~/PhoenixClaw/Journal/daily/YYYY-MM-DD.md and extracts structured personal content, yet it provides no user-facing disclosure that private diary entries will be accessed. Since journals are highly sensitive by nature, automatically reading them based on a request like 'generate today's log share image' can violate user expectations and leak intimate information into downstream outputs.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

L057-L058 将“对话”“聊天”“今天聊了什么”等常见日常表达作为识别特征和触发词,这些短语在普通交流中非常常见,缺少足够的任务边界。文档也没有提供排除条件或负面示例来说明何时不应激活聊天记录解析,因此存在意外调用该技能的风险。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documentation states it will scan local session files under ~/.openclaw/sessions/*.jsonl and filter messages by date, but it does not require user notice or explicit consent for accessing those records. Because chat logs can contain sensitive personal or operational information, silent local scanning creates a privacy risk and could expose more data than the user expected from a vague summarization request.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

SQP-3 applies to all file types and covers language/locale policy violations. This markdown file presents all instructions and operational guidance only in Chinese, with no indication that users may choose another language or that the file is intentionally limited to a Chinese-only audience for a documented regional reason.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/rendering-setup.md (reported line 133)May include surrounding context.

brew install font-noto-sans-cjk

Ubuntu/Debian

sudo apt-get install fonts-noto-cjk

text

### 权限问题 (Linux)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document explicitly advises use of --no-sandbox --disable-setuid-sandbox for Chromium-based rendering. Disabling the browser sandbox materially weakens a key isolation boundary; in a skill that renders HTML/CSS and may process user-controlled content, a browser compromise would have a much easier path to affect the host environment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script renders HTML built from user-controlled content in a real browser context via Playwright and waits for networkidle, which permits outbound requests triggered by HTML/CSS during rendering. Even though templates are local, unescaped user data can be embedded into markup and cause external resource loads or SSRF-like behavior, which exceeds the stated purpose of offline image generation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The comment "Usage: 长文章、博客、公众号推文" describes the template in Chinese and implies a locale-specific intended use, but the file provides no indication that language or locale is optional or user-selectable. Under the policy rule, forcing or assuming a specific language/locale without opt-in can be a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The comment "Usage: PhoenixClaw 完整日志" includes a Chinese-only usage label, which indicates a language-specific constraint in the file without any accompanying opt-in or alternative language guidance. This can conflict with organizational language/locale policies when the skill does not explicitly offer user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This HTML template includes Chinese natural-language content in comments and visible labels, which indicates the skill may force a specific language/locale. The file does not provide any user opt-in, alternative locale, or justification that the template is intended only for a Chinese-language or region-specific context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This HTML file contains a natural-language comment, "单张照片 + 描述", that forces a specific language in the skill artifact without any indication of user opt-in or justified locale restriction. The applicable policy category covers all file types, including comments in template files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The comment Usage: 名言、哲理、简短感悟 specifies the template's intended use only in Chinese, which can be interpreted as a language-specific constraint. The file does not offer any language choice or explain that this locale restriction is intentional or region-specific.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency uses a caret version range, which allows newer minor/patch releases to be installed over time. This creates supply-chain risk because builds are not fully reproducible and a compromised or breaking upstream release could be pulled in without an explicit review. In this skill, the package participates in HTML-to-image generation and may process untrusted content, so silently changing transitive code is a real but low-severity risk.

Content

Scanner excerpt · package.json (reported line 10)May include surrounding context.

json
"generate": "node scripts/generate-image.js"
  },
  "dependencies": {
    "node-html-to-image": "^5.0.0"
  },
  "optionalDependencies": {
    "playwright": "^1.58.2"

Static analysis

No suspicious patterns detected.