Back to skill

Security audit

Saas Founder Content Writer

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent content-writing helper, but its image renderer can open HTML with browser network access despite claiming no network is needed.

Install only if you are comfortable reviewing the renderer first. Render only trusted, self-contained HTML, consider adding request blocking or disabling JavaScript, audit/update the Puppeteer dependency chain before npm install, and verify the resolved vault path before enabling save-to-vault auto-saving.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render-image.js:130
Finding

Unrestricted Network Access While Rendering Arbitrary HTML

Content
View full analysis

Vulnerability Details

File Location: scripts/render-image.js, lines 130–131
Vulnerability Type: Arbitrary HTML execution with unrestricted browser networking
Risk Level: Medium

Vulnerable Code

js
await page.goto("file://" + path.resolve(inputPath), { waitUntil: "networkidle0" });
await page.screenshot({ path: outputPath, fullPage: opts.full });

The script also makes an inaccurate security claim at scripts/render-image.js:19:

js
 * No credentials, tokens, or network access are required.

A similar claim appears in render-image-setup.md:5:

md
No credentials, tokens, or network access are required.

Technical Analysis

The renderer accepts a caller-selected HTML file and opens it in a fully script-capable Chromium page. It does not disable JavaScript, intercept network requests, enforce an offline content policy, or restrict resource destinations.

Although the bundled templates contain no scripts or external resources, the renderer itself does not enforce that property. A crafted input document can therefore execute JavaScript and load remote scripts, images, stylesheets, fonts, frames, or other network resources. Chromium's sandbox reduces the likelihood of direct host compromise, but it does not prevent outbound network communication.

This conflicts with the documented self-contained, network-free rendering model. The risk is especially relevant if attacker-controlled post content is inserted into generated HTML without correct context-sensitive escaping.

Attack Path

  1. An attacker supplies content that is incorporated into an HTML card, or convinces the user or agent to render an attacker-controlled HTML file.
  2. The resulting document contains an active payload, such as a script, remote image, stylesheet, iframe, or other external resource.
  3. The user or agent invokes scripts/render-image.js with that document as the input.
  4. Puppeteer opens the document with JavaScript and browser networking e ...[truncated 1044 chars]
Remediation
View remediation

Remediation Suggestions

  1. Enforce an offline request policy. Enable Puppeteer request interception before navigating and reject every request except explicitly permitted local schemes:
js
await page.setRequestInterception(true);

page.on("request", (request) => {
  const url = new URL(request.url());

  if (url.protocol === "file:" || url.protocol === "data:") {
    request.continue();
  } else {
    request.abort("blockedbyclient");
  }
});
  1. Disable JavaScript by default if the templates do not require it:
js
await page.setJavaScriptEnabled(false);

If JavaScript is required in the future, expose it only through an explicit opt-in option and retain strict network blocking.

  1. Validate the input path. Resolve the path, confirm that it is a regular file, reject unsupported extensions, and optionally restrict inputs to an approved workspace directory.

  2. Escape user-controlled content. Use context-sensitive escaping before placing user material into HTML text, attributes, URLs, CSS, or script contexts. Prefer DOM text assignment or a template system with automatic escaping over string concatenation.

  3. Add a restrictive Content Security Policy to generated templates, for example:

html
<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'none'; img-src data: file:; style-src 'unsafe-inline'; font-src data: file:; script-src 'none'"
/>

Request interception should remain the primary control because the renderer accepts arbitrary HTML that may omit or weaken a document-level policy.

  1. Correct the documentation. Do not claim that network access is absent until the renderer technically enforces that guarantee. Clearly state whether untrusted HTML is supported.

  2. Add automated security tests. Render a test document that attempts HTTP, HTTPS, iframe, image, stylesheet, and script requests. The test should fail unless every external request is blocked.

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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
85% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

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

md
| K5 | Comparison | Two options people confuse | Contrast on the axis that actually decides it. |
| K6 | "What this means for you" | News/tech the reader should act on | Translate the development into a concrete reader action. |

Knowledge posts carry no product CTA. The "Useful before promotional" principle becomes "useful before instructive": teach, don't lecture.

---

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/render-image.js <input.html> <output.png> [--width=1080] [--height=1440] [--scale=2]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/render-image.js <input.html> <output.png> [--width=1080] [--height=1440] [--scale=2]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/render-image.js <input.html> <output.png> [--width=1080] [--height=1440] [--scale=2]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/render-image.js <input.html> <output.png> [--width=1080] [--height=1440] [--scale=2]

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
95% confidence
Finding

The lockfile pins extract-zip 2.0.1, which is reported vulnerable to arbitrary file write and symlink path traversal during ZIP extraction. Even though this file is only a dependency manifest, the vulnerable package is transitively included via Puppeteer’s browser download/extraction path, so a malicious archive or compromised download source could potentially write outside the intended extraction directory.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.2.0 — 3 advisory(ies): CVE-2026-54272 (ip-address: misclassification of IPv4-mapped/NAT64 IPv6 addresses can bypass SSR); CVE-2026-69198 (ip-address: a CIDR suffix on the parsed address suppresses special-use classific); CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco)

High
Category
Supply Chain
Confidence
80% confidence
Finding

The lockfile includes ip-address 10.2.0, which has advisories for incorrect classification/parsing of special-use and mapped IP formats. In this package set it is only a transitive dependency under proxy/SOCKS handling, so the issue becomes dangerous if the skill or its runtime relies on this library for SSRF protection, proxy allow/deny logic, or trust decisions around user-influenced network targets.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.2.0 — 3 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)

High
Category
Supply Chain
Confidence
83% confidence
Finding

The lockfile pins js-yaml 4.2.0, which is associated with CPU denial-of-service issues from crafted YAML merge structures and omap resolution. Here it is a transitive dependency of cosmiconfig used by Puppeteer, so risk depends on whether attacker-controlled YAML configuration files can be loaded in the execution environment; if so, parsing such files could cause excessive CPU use or process slowdown.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Line L44 describes 'Chinese-by-default behavior' for Xiaohongshu support. Forcing a specific language by default is a natural-language policy concern unless the skill offers user choice or clearly justifies a region-specific constraint; this changelog entry does not mention either.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill references code-capable behavior involving environment variables but does not declare any tool scope or allowed-tools boundary. That creates ambiguity about what runtime capabilities the skill may exercise and weakens least-privilege controls, especially because the skill later uses environment-derived paths to drive file writes.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
- **Floor:** 1 (cover only, when the body is a single short thought).
- **Ceiling:** Xiaohongshu allows at most 18 images — never exceed it; if the draft would imply more, group related points onto one card.

State the resulting plan in the image brief (the `Cards:` line below), then render or spec all of them in one pass — no confirmation prompt.

An image is useful for:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill is presented as a content-drafting tool, but it also instructs the agent to write files and copy rendered images into the user's vault. This is a scope expansion from generation to persistent filesystem modification, which can surprise users, create integrity risks in personal notes, and be abused to plant content or overwrite data if execution boundaries are weak.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill reads OBSIDIAN_VAULT_PATH from the environment to choose a filesystem write target, which introduces an external, potentially attacker-influenced sink for persistent writes. Even with path announcement, relying on ambient environment state increases the chance of writing sensitive content to an unintended location or a path manipulated by another component.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill sets a platform-specific default language of Chinese for Xiaohongshu, even though the broader skill policy earlier says to match the founder's input unless they specify otherwise. This creates a locale policy issue because it forces a specific language without explicit opt-in or a documented compliance justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script claims that no network access is required, but it loads attacker-controlled HTML in a real browser and waits for "networkidle0", which permits the page to fetch remote images, fonts, CSS, scripts, or beacon requests referenced by the HTML. In this skill context, the HTML is likely generated from user/content inputs for social-media assets, so untrusted markup could trigger outbound network requests, leak metadata or local file-derived content via embedded requests, and produce nondeterministic rendering dependent on external resources.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The document sets lang="zh", which imposes a specific language/locale in the template. The file does not offer any user opt-in or explain that the template is intended only for a Chinese-language or region-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file sets the document language to Chinese using a fixed locale value, which is a natural-language policy concern when the skill does not offer user opt-in or explain why the locale is required. The rest of the template includes English display text, reinforcing that the language setting is imposed rather than clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document declares lang="zh", which sets a specific language/locale for the skill output without any visible user opt-in or explanation. Under the policy, forcing a language or locale is a natural-language policy issue unless the constraint is explicitly justified or optional.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 13)May include surrounding context.

json
"node": ">=18"
  },
  "dependencies": {
    "puppeteer": "^24.15.0"
  }
}

Static analysis

No suspicious patterns detected.