Back to skill

Security audit

Content Card

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent PNG-card purpose, but it renders untrusted content through executable HTML/Chromium paths with networking enabled and insufficiently documented safeguards.

Install only if you are comfortable with the skill running Node/Playwright, creating local HTML and PNG files, and rendering supplied web/file content in a browser context. Avoid using it on sensitive or adversarial content until templates sanitize inputs, JavaScript is disabled where unnecessary, outbound network requests are blocked, and dependencies are pinned.

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

Warning
Location
assets/infograph_template.html:6
Finding

Unnecessary External Font Request During Local Rendering

Content
View full analysis
@import url('https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=DM+Sans:wght@400;500;700&display=swap'); ``` The template is rendered by Playwright as follows: ```javascript const fileUrl = 'file://' + path.resolve(htmlPath); await page.goto(fileUrl, { waitUntil: 'networkidle' }); await page.waitForTimeout(500); ``` ### Technical Analysis The infographic template imports fonts from Google Fonts whenever Chromium renders the generated HTML. Although the primary input document is loaded through a local `file://` URL, the browser retains unrestricted network access. Consequently, a nominally local content-to-PNG operation generates an outbound request to Google. The remote request is not required for the Skill's core functionality because the template already declares fallback system fonts. This behavior exceeds the minimum privileges needed to render a PNG. The request can disclose the host's public IP address, request timing, browser request headers, and the fact that the Skill is being used. It also makes output generation dependent on an external, mutable service. ### Attack Path 1. A user invokes the Skill in infographic mode. 2. The Skill generates HTML from `assets/infograph_template.html`. 3. `scripts/capture.js` opens the resulting local HTML document in Chromium. 4. Chromium evaluates the CSS `@import`. 5. Chromium sends an outbound request to `fonts.googleapis.com`. 6. Google or an intermediary can observe the request metadata, and rendering may block or change depending on the remote response. ### Impact Assessment This issue does not grant local code execution or elevated operating-system privileges. Its scope is network-level privacy leakage and loss of determinis ...[truncated 343 chars]
Remediation
View remediation
{ const url = new URL(route.request().url()); if (url.protocol === 'file:' || url.protocol === 'data:') { await route.continue(); } else { await route.abort(); } }); ``` 5. Register request interception before calling `page.goto`. 6. If remote assets are explicitly required in a future feature, use a documented hostname allowlist and require user consent. 7. Add an automated test that fails when generated templates attempt an HTTP or HTTPS request. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
assets/infograph_template.html:70
Finding

Untrusted Content Can Reach Executable HTML and CSS Template Contexts

Content
View full analysis
{{CONTENT_HTML}} ``` The long-form template similarly inserts generated content into HTML contexts: ```html {{TITLE_BLOCK}} {{BODY_HTML}} {{AUTHOR_NAME}} {{SOURCE_LINE}} ``` The Skill instructions describe direct placeholder replacement without prescribing sanitization: ```markdown 将内容填充到模板的 `{{VARIABLE}}` 占位符中。 ``` The resulting document is then loaded by Chromium: ```javascript const fileUrl = 'file://' + path.resolve(htmlPath); await page.goto(fileUrl, { waitUntil: 'networkidle' }); ``` ### Technical Analysis The Skill accepts content from pasted text, local files, and fetched URLs. It then places generated values into raw HTML, CSS, attribute, and URL contexts. The documented generation process does not require: - HTML sanitization - Context-sensitive output encoding - A URL-scheme allowlist - Removal of event-handler attributes - Removal of `
Remediation
View remediation
`, ``, `<object>`, `<embed>`, `<link>`, `<meta>`, and `<base>`. - Remove all `on*` event-handler attributes. - Remove dangerous schemes such as `javascript:`. - Reject remote `http:` and `https:` resources unless explicitly approved. 5. Do not accept arbitrary CSS. Generate CSS only from typed, validated values such as enumerated style names and validated color tokens. 6. Validate `LOGO_PATH` and other resource attributes against an allowlist of local paths or safe `data:` image URLs. 7. Add a restrictive Content Security Policy, for example: ```html <meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' file: data:; style-src 'unsafe-inline'; font-src 'self' file: data:; script-src 'none'; connect-src 'none'; frame-src 'none'; object-src 'none'; base-uri 'none'"> ``` 8. Disable JavaScript in the screenshot page when templates do not require it: ```javascript const context = await browser.newContext({ javaScriptEnabled: false }); const page = await context.newPage(); ``` 9. Intercept network requests and abort all non-local schemes before navigation. 10. Add security tests using payloads containing script elements, event attributes, CSS imports, remote images, iframes, and `javascript:` URLs. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
assets/widgets/card-preview.html:7
Finding

Unsafe Inline Script Data-Injection Contract in Card Preview Widget

Content
View full analysis
window.__SKILL_DATA__ = {...}; here --> ``` The inserted object is then trusted by the preview: ```javascript root.innerHTML = '
加载中…
'; if (window.__SKILL_DATA__) { data = window.__SKILL_DATA__; render(); } else { ``` ### Technical Analysis The documented data-transfer mechanism places serialized card data directly inside a `` sequence. JSON serialization by itself does not necessarily make arbitrary data safe for inline HTML script contexts. If an attacker-controlled title, URL, or another card field contains a script terminator, the HTML parser can end the intended script element before the JavaScript parser processes the object. The remainder can then be interpreted as attacker-controlled HTML or JavaScript. The `esc()` helper later used during rendering does not mitigate this issue. It runs only after the browser has parsed and executed the injected script block. The vulnerable boundary is therefore the initial serialization into the document, not the later insertion into `root.innerHTML`. The repository does not contain the implementation that performs this documented injection, so the exploitability depends on whether the caller applies context-safe serialization. The contract itself is unsafe because it directs callers toward executable inline insertion without requiring that protection. ### Attack Path 1. An attacker controls a card field derived from ...[truncated 1202 chars]
Remediation
View remediation
{"title":"...","cards":[]} ``` 3. Read the data through `textContent`: ```javascript const node = document.getElementById('skill-data'); data = JSON.parse(node.textContent); ``` 4. When embedding JSON into HTML, escape `<` as `\u003c` so `` cannot terminate the element. Also handle Unicode line and paragraph separators where relevant. 5. Prefer loading a local `data.json` file over generating executable JavaScript assignments. 6. Validate the parsed object against a strict schema: - Require expected primitive types. - Limit string lengths. - Restrict `imageUrl` to approved local or `data:image/...` URLs. - Reject unknown properties if they are unnecessary. 7. Add a Content Security Policy that blocks inline and external scripts except for a fixed, hash-authorized widget script. 8. Add regression tests with values containing ``, HTML elements, quotes, backslashes, and Unicode separator characters. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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 (29)

Hidden Instructions

High
Category
Prompt Injection
Confidence
88% confidence
Finding

The file explicitly relies on an agent injecting a raw . Injecting untrusted data into an inline script context is dangerous because attacker-controlled content can break out of the JavaScript object/JSON literal (for example via or crafted strings) and execute arbitrary script in the page, which is especially relevant here because the skill renders user-provided content/URLs into a preview UI.

Content

Scanner excerpt · assets/widgets/card-preview.html (reported line 7)May include surrounding context.

html
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Content Card Preview</title>
<!-- DATA_INJECTION_POINT: Agent will insert <script>window.__SKILL_DATA__ = {...};</script> here -->
<style>
  *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README describes the skill entirely in Chinese, including usage and behavior, with no indication that users can choose another language or that the skill is region-specific. Under the policy rules, forcing a specific language or locale without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description and main instructions are written as directives in Chinese, including trigger phrases and operational guidance, with no indication that other languages are supported or that the user can opt into a preferred language. This creates a natural-language locale constraint that is not documented as region-specific or optional.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill goes beyond passive content formatting by directing execution of Node, npm, and a local capture script. Any skill that triggers package installation or local script execution expands the attack surface substantially, especially when the script path is outside the immediate document and its contents are not described or integrity-checked.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

The skill instructs use of npx playwright without pinning a specific version, which allows the latest package version to be resolved at runtime. That introduces supply-chain and reproducibility risk: a compromised or breaking upstream release could execute unexpected code on the host during installation or browser setup.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The HTML document hard-codes lang="zh-CN", which imposes a specific language/locale in the rendered output. For a general-purpose skill template, this is a natural-language policy concern unless the locale is optional or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The HTML root element forces the document language to zh-CN, which is a locale-specific setting expressed in natural language metadata. There is no indication in this file that the locale is optional, user-selected, or justified as a region-specific template, so it may violate the policy against forcing a specific language or locale without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document declares lang="zh-CN", and the UI strings throughout the file are written in Simplified Chinese. This forces a specific language/locale experience without any visible user opt-in or justification that the skill is intended only for Chinese-language users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill writes a PNG directly into the user's Downloads folder, modifying user files without an explicit warning or confirmation. In this skill context the write is aligned with the advertised purpose, but Downloads is a user-visible persistent location, so silent output can cause unwanted file creation, overwrite/collision risk, or leakage of sensitive content into a broadly accessible folder.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill constructs and runs an external shell command invoking Node.js with file-path placeholders derived from content/name values. If those placeholders are not strictly sanitized and shell-escaped, this creates command-injection risk or unintended execution of local code; even absent injection, spawning an external subprocess expands the attack surface beyond simple content formatting.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire skill guidance is written exclusively in Chinese and does not indicate that users may choose another language or locale. Per the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified, which it is not here.

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.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The manifest describes accepting text, URLs, and files as content inputs, but these lines add implicit reading of .content-card/EXTEND.md and ~/.config/content-card/EXTEND.md. Accessing extra local files outside the user's provided content is a behavioral extension not communicated in the skill description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The workflow stores structured intermediate content in temp/content-card/structured-content.md and reuses it if the content appears unchanged. Because the input may include sensitive text from URLs or files, this creates an unintended persistence layer that can retain confidential material longer than expected and expose it to other local processes or users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The HTML root element hard-codes lang="zh-CN", which imposes a specific language/locale on all rendered output. For this file, there is no surrounding natural-language explanation that this template is region-specific or that users can opt into another locale.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency uses a caret range (^1.52.0), which allows automatic installation of newer minor and patch releases rather than a single fixed version. This can introduce supply-chain risk if a future release contains a vulnerability, breaking change, or compromised package, though the risk here is limited because the file only declares a common third-party dependency and does not show any additional dangerous install behavior.

Content

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

json
"version": "1.0.0",
  "private": true,
  "dependencies": {
    "playwright": "^1.52.0"
  }
}

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

Line L17 specifies lang: zh as the default language. This is a natural-language locale constraint, and the file does not indicate that users can choose another language or opt in to this default, which may conflict with language-choice policy expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown skill instructs writing generated output to /tmp/ljg_cast_infograph_{name}.html, which affects the local filesystem. The document does not include any warning or disclosure to the user that a file will be created, so the behavior may be unexpected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The screenshot step saves a PNG to ~/Downloads/{name}.png, which modifies user data by creating a file in a user-visible directory. The markdown does not explicitly warn that running this step will produce an output file in Downloads.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly instructs the agent to write a generated HTML file into /tmp, which is a real filesystem side effect without any user notice or consent step. While /tmp is a transient location and the behavior is consistent with rendering a card, it still creates local files and could expose sensitive rendered content to other local processes or leave artifacts unexpectedly.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The manifest presents the skill as converting content into high-quality PNG cards, but this file explicitly instructs writing temporary HTML files and persistent output files to user-accessible locations. While file generation is expected for image rendering, the additional documented write behavior is broader than the high-level description suggests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown skill instructs writing generated content to /tmp/ljg_cast_poster_{name}_{N}.html, which affects local filesystem state. The document does not provide any warning that intermediate files will be created or retained on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The markdown includes a node ... capture.js command to generate screenshots, which is a subprocess execution affecting the user's system. There is no explicit disclosure in the document that the skill will run a local command as part of processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The screenshot command writes image files to ~/Downloads/{name}_{N}.png, which creates persistent user-visible files. The skill description does not warn the user that generated images will be saved in Downloads.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file’s title and all descriptive guidance are written in Chinese, and it does not indicate that other languages are supported or that Chinese is an intentional opt-in. Under the policy for natural-language constraints, this can be considered a locale/language preference that is imposed without user choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.