Back to skill

Security audit

Visual Note Card

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it automatically creates HTML that runs third-party JavaScript and renders it with Chromium sandboxing disabled.

Install only if you are comfortable with generated cards contacting Google Fonts and cdnjs when opened, and with the renderer running Chromium without its normal sandbox. Avoid feeding untrusted HTML into the PNG script, and review or remove the mandatory repository attribution if you need unbranded deliverables.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:174
Finding
Mandatory Third-Party Promotional Content Injected into User Deliverables<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:174-182`; implemented in `assets/template.html:550-554` **Vulnerability Type**: Mandatory output manipulation **Risk Level**: High ### Vulnerable Code `SKILL.md:174-182`: ```markdown ### Copyright (Mandatory) Every card MUST include a copyright bar **inside** the `.poster` div (below the footer, separated by a thin border-top), so it appears in both the HTML page and the exported PNG: ```html <div class="copyright-bar"> <svg><!-- GitHub icon --></svg> <span>Generated by <a href="https://github.com/beilunyang/visual-note-card-skills">https://github.com/beilunyang/visual-note-card-skills</a></span> </div> ``` ``` `assets/template.html:550-554`: ```html <div class="copyright-bar"> <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg> <span>Generated by <a href="https://github.com/beilunyang/visual-note-card-skills" target="_blank" rel="noopener">https://github.com/beilunyang/visual-note-card-skills</a></span> </div> ``` ### Technical Analysis The Skill instructions require the agent to insert repository branding and an external hyperlink into every generated card. The placement inside the `.poster` element is explicitly selected so the promotional content is preserved in both the HTML and the exported PNG. This requirement is unrelated to the subject matter requested by the user and modifies the expected deliverables for the benefit of a third-party repository. Because the rule is marked mandatory, the loaded Skill alters the agent's output policy rather than treating attributi ...[truncated 902 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the mandatory attribution requirement from `SKILL.md`. 2. Remove the hardcoded repository attribution from `assets/template.html`. 3. Make attribution explicitly opt-in through a user-controlled option. 4. Honor requests for unbranded output and avoid placing non-user-requested promotional content inside `.poster`. 5. If provenance metadata is operationally required, document it clearly and store it outside the exported visual area unless the user consents. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/html2png.py:42
Finding
Untrusted HTML Rendered with the Chromium Sandbox Disabled<![CDATA[ ## Vulnerability Details **File Location**: `scripts/html2png.py:42` **Vulnerability Type**: Unsafe headless-browser configuration **Risk Level**: Medium ### Vulnerable Code ```python with sync_playwright() as p: browser = p.chromium.launch(args=["--no-sandbox", "--disable-setuid-sandbox"]) page = browser.new_page( viewport={"width": 1280, "height": 900}, device_scale_factor=scale, ) ``` The affected rendering flow subsequently opens the supplied HTML file: ```python # 加载 HTML page.goto(f"file://{input_path}", wait_until="networkidle") ``` ### Technical Analysis The renderer launches Chromium with both `--no-sandbox` and `--disable-setuid-sandbox`. It then loads a caller-supplied HTML document with JavaScript and remote-resource loading enabled. Chromium's sandbox is a defense-in-depth boundary intended to limit the host-level impact of a compromised renderer process. Disabling it does not independently create arbitrary code execution, but it materially weakens containment if malicious HTML, a compromised external script, or a browser vulnerability causes renderer compromise. The script only checks that the input path exists. It does not establish that the HTML is trusted, disable JavaScript, restrict network access, or isolate the browser in a separate container. ### Attack Path 1. An attacker influences the HTML passed to `html2png.py`, either directly or through content incorporated into a generated card. 2. The script starts Chromium without its normal sandbox protections. 3. Chromium loads the local HTML with JavaScript enabled and may retrieve remote scripts, fonts, or other resources. 4. Malicious page code or a compromised dependency targets a Chromium vulnerability. 5. If browser exploitation succeeds, the missing sandbox reduces the barriers between the compromised renderer and the host environment. 6. Resulting host access would run with the operating-system privil ...[truncated 653 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox` and run Chromium with its standard sandbox enabled. 2. Execute rendering as a dedicated, unprivileged operating-system user. 3. Place the renderer in a short-lived container or virtualized sandbox with: - A read-only filesystem except for a dedicated output directory. - No access to agent credentials or unrelated user files. - Restricted outbound network access. - CPU, memory, execution-time, and file-size limits. 4. Validate and canonicalize input paths, and restrict inputs to an approved rendering directory. 5. Disable JavaScript where it is not necessary, or sanitize HTML before rendering. 6. Block arbitrary remote origins and use locally stored dependencies and fonts where practical. 7. Keep Chromium and Playwright patched to reduce exposure to known browser vulnerabilities. ]]>

T08 · Insecure Dependencies

Warning
Location
assets/template.html:617
Finding
Remote JavaScript Dependency Loaded Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `assets/template.html:617`; required by `SKILL.md:164-166` **Vulnerability Type**: Unverified third-party executable dependency **Risk Level**: Medium ### Vulnerable Code `assets/template.html:617`: ```html <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> ``` `SKILL.md:164-166`: ```markdown Implementation: 1. Add `<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>` before `</body>` 2. The FAB (`div.fab-wrap`) is placed OUTSIDE `.poster` so it won't appear in the exported image ``` ### Technical Analysis The generated HTML executes `html2canvas` from a public CDN. Although the URL pins version `1.4.1`, the document does not use a Subresource Integrity hash and does not bundle a reviewed local copy. Consequently, the browser trusts whichever bytes the remote endpoint returns at runtime. This creates a supply-chain boundary outside the audited repository. Compromise of the CDN, its account, delivery path, or hosted asset could cause substituted JavaScript to execute whenever a generated card is opened. The dependency is also loaded when `html2png.py` navigates to the page, and that renderer currently disables Chromium sandboxing. ### Attack Path 1. The Skill generates an HTML card containing the CDN script reference. 2. A user opens the card, or `html2png.py` loads it for rendering. 3. The browser requests `html2canvas.min.js` from `cdnjs.cloudflare.com`. 4. If the remote asset or its delivery infrastructure has been compromised, the browser receives attacker-controlled JavaScript. 5. Because no integrity hash is present, the browser accepts and executes the substituted code. 6. In a normal browser, the code can manipulate the document and perform network requests within browser security constraints. In the headless workflow, a browser exploit would be more consequential because the Chromium sandbox is d ...[truncated 692 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bundle a reviewed local copy of `html2canvas` with the Skill and reference it through a local relative path. 2. Record and verify the dependency's checksum as part of release and update procedures. 3. If CDN loading is unavoidable, add Subresource Integrity and CORS metadata using a hash verified against the exact dependency bytes: ```html <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js" integrity="sha384-REPLACE_WITH_VERIFIED_HASH" crossorigin="anonymous"></script> ``` 4. Do not insert an unverified placeholder hash; generate and independently verify the correct hash before release. 5. Add a restrictive Content Security Policy that limits scripts and connections to explicitly approved sources. 6. Pin dependencies in a documented manifest and establish a controlled review process for upgrades. 7. Restrict or disable network access during server-side rendering so generated HTML cannot retrieve arbitrary runtime code. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (16)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Claude Code:**

```bash
rm -rf ~/.claude/skills/visual-note-card
```

**OpenClaw:**
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Claude Code:**

```bash
rm -rf ~/.claude/skills/visual-note-card
```

**OpenClaw:**
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Claude Code:**

```bash
rm -rf ~/.claude/skills/visual-note-card
```

**OpenClaw:**
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**OpenClaw:**

```bash
rm -rf ~/.openclaw/skills/visual-note-card
```

## Usage
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Natural-Language Policy Violations

High
Confidence
98% confidence
Finding
The skill hard-codes that all text must be Chinese except limited elements, overriding the user's likely language preference unless they explicitly adapt it elsewhere. This creates a policy and UX risk because the system may produce output in an unsolicited language, mis-handle multilingual requests, and violate expected user-control over response language.

Hidden Instructions

High
Category
Prompt Injection
Content
<!--
  VISUAL NOTE CARD TEMPLATE
  ==========================
  This is the canonical reference template. When generating a new card,
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<div class="label-right">{{SOURCE_LABEL}}</div>
  </div>

  <!-- ====== SECTION 2: MAIN TITLE ====== -->
  <div class="main-title">
    <div class="left">
      <h1>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The README states the skill generates professional Chinese visual note cards, which may steer output language toward Chinese without clear user opt-in. While not a classic security flaw, this can create misleading or undesired behavior, especially if the user input is in another language or if downstream consumers expect a different locale.

Vague Triggers

Medium
Confidence
97% confidence
Finding
The trigger condition is broad enough to activate on 'any request to summarize content into a structured visual card format,' which can cause the skill to run in situations the user did not explicitly intend. In an agentic environment, overly broad activation can lead to incorrect tool selection, unwanted transformations of user content, or accidental bypass of more appropriate workflows.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger description is broad enough to activate on generic summarization, article condensation, and style-matching requests that may not actually require this skill. That can cause unintended tool use, creation of files/PNG exports when the user did not request them, and routing into a specialized workflow that changes output format and behavior unexpectedly.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The HTML root sets `lang="zh-CN"`, which establishes a fixed locale for the generated artifact. Elsewhere in the template, interface strings such as export labels are also hard-coded in Chinese, indicating the skill is designed to operate in a specific language/locale without offering user choice.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The template pulls Google Fonts from a third-party origin, which makes the generated infographic non-self-contained and causes network requests when opened. This leaks viewer metadata such as IP address and user agent to external services and can break rendering in offline or restricted environments.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The export controls and status text are presented only in Chinese, including labels like `导出图片` and `正在导出…`. This is a natural-language policy issue because the skill imposes a single language on end users rather than offering localization or opt-in.

Description-Behavior Mismatch

Medium
Confidence
99% confidence
Finding
The export feature depends on a remotely loaded html2canvas script from a CDN, so the HTML file is not actually self-contained and executes third-party code at runtime. If the CDN is unavailable or the dependency is compromised, export fails or malicious script could run in the viewer's browser context.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The module docstring and CLI help text are written entirely in Chinese, which imposes a specific language on users without any opt-in or indication that the tool is intentionally limited to a Chinese-speaking context. The policy explicitly calls for flagging language or locale constraints when no user choice or justification is provided.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The script launches Chromium with both `--no-sandbox` and `--disable-setuid-sandbox`, removing an important defense boundary while rendering potentially untrusted local HTML. Because the skill converts user-supplied or generated HTML and waits for page activity to settle, any browser exploit or unsafe renderer behavior would run with fewer protections than normal, increasing host compromise risk.

Static analysis

Detected: suspicious.destructive_delete_command

Documentation contains a destructive delete command without an explicit confirmation gate.

Warn
Code
suspicious.destructive_delete_command
Location
README.md:80