Back to skill

Security audit

Baoyu Markdown To Html

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it advertises, but it needs review because it can download a runtime at use time and fetch image URLs embedded in Markdown with the user's machine access.

Review before installing. Prefer using a preinstalled, trusted Bun runtime instead of the `npx -y bun` fallback, and convert only trusted Markdown or remove/check remote image URLs first. Run it with limited filesystem and network access if possible, and expect it to create or replace HTML output files, backups, and Mermaid cache files beside the input.

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

Warning
Location
scripts/main.ts:141
Finding

Unrestricted Remote Image Resolution Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/main.ts, lines 141–148
Vulnerability Type: Server-Side Request Forgery through remote image resolution
Risk Level: Medium

Vulnerable Code

ts
const hasRemoteImages = images.some((image) =>
  image.originalPath.startsWith("http://") || image.originalPath.startsWith("https://"),
);
const tempDir = hasRemoteImages
  ? fs.mkdtempSync(path.join(os.tmpdir(), "markdown-to-html-"))
  : baseDir;
const contentImages = await resolveContentImages(images, baseDir, tempDir, "markdown-to-html");

Technical Analysis

Remote image URLs extracted from attacker-controlled Markdown are passed to resolveContentImages without application-level validation of the destination host, resolved IP address, redirect targets, or network range.

Checking only whether a value begins with http:// or https:// does not prevent requests to loopback, link-local, private-network, or cloud metadata addresses. The conversion process may therefore act as a server-side HTTP client with access to network resources unavailable to the attacker.

The implementation shown also does not impose explicit response-size, timeout, redirect-count, or content-type restrictions at the call site. The dependency's internal safeguards were not available in the audited project, so the SSRF finding is based on the absence of destination controls before invoking it.

Attack Path

  1. An attacker provides a Markdown file to a user or service that invokes this Skill.

  2. The Markdown contains an image reference to a sensitive network destination, for example:

    markdown
    ![probe](http://169.254.169.254/latest/meta-data/)
    

    Alternatively, the URL may target 127.0.0.1, an RFC 1918 private address, an internal hostname, or a public hostname that redirects to one of those destinations.

  3. replaceMarkdownImagesWithPlaceholders extracts the image URL.

  4. The code recognizes the URL as an HTTP or HTTPS resource.

  5. The unvalid ...[truncated 986 chars]

Remediation
View remediation

Remediation Suggestions

  • Disable remote image retrieval by default and require an explicit option to enable it.
  • Prefer an allowlist of trusted HTTPS origins.
  • Parse URLs with the platform URL parser and reject embedded credentials, unsupported schemes, malformed ports, and ambiguous host representations.
  • Resolve the hostname before connecting and reject loopback, link-local, private, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
  • Repeat destination validation after every DNS resolution and every redirect to prevent DNS rebinding and redirect-based bypasses.
  • Block cloud metadata destinations such as 169.254.169.254 and platform-specific metadata hostnames.
  • Apply strict connection, read, and total-operation timeouts.
  • Limit redirect count and downloaded response size.
  • Validate the response Content-Type and accept only required image formats.
  • Stream downloads with a hard byte limit rather than buffering unrestricted responses.
  • Add tests covering loopback, private IPv4, IPv6 loopback, link-local addresses, redirects to private hosts, DNS rebinding behavior, oversized responses, and timeout handling.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:29
Finding

Automatic Execution of an Unpinned Runtime Package

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 29–30 and line 92
Vulnerability Type: Unsafe third-party runtime acquisition and execution
Risk Level: Medium

Vulnerable Instructions

md
**Agent Execution**: Determine this SKILL.md directory as `{baseDir}`. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `{baseDir}` and `${BUN_X}` with actual values.
bash
${BUN_X} {baseDir}/scripts/main.ts <markdown_file> --theme <theme> [--cite]

Technical Analysis

When a trusted local Bun executable is unavailable, the Skill directs the Agent to run:

bash
npx -y bun

This command automatically resolves, downloads, and executes the package currently published under the bun name. No exact version or integrity value is specified. The -y option suppresses the normal confirmation prompt, so third-party code may be acquired and executed without explicit user approval.

Although the project contains an integrity lockfile for its application dependencies, that lockfile does not pin or verify the runtime package downloaded by this npx fallback. The effective executable can therefore change after the Skill has been reviewed.

This is a supply-chain exposure rather than evidence that the current package is malicious.

Attack Path

  1. The Skill runs in an environment where bun is not already installed.
  2. npx is available.
  3. Following SKILL.md, the Agent substitutes ${BUN_X} with npx -y bun.
  4. npx resolves and downloads the package version selected by the package registry at execution time.
  5. Package code executes with the same operating-system identity and permissions as the Agent.
  6. If the package, registry account, distribution channel, or resolved package version is compromised, attacker-controlled code executes before or while the local Markdown converter is launched.

Impact Assessment

A compromised runtime package coul ...[truncated 642 chars]

Remediation
View remediation

Remediation Suggestions

  • Prefer a preinstalled, administrator-managed Bun executable from a trusted distribution channel.
  • Remove the automatic npx -y bun fallback.
  • If runtime acquisition is necessary, require explicit user confirmation before downloading or executing it.
  • Pin the runtime to a specifically audited version instead of resolving the latest compatible publication.
  • Verify the downloaded artifact with a trusted cryptographic checksum or signature.
  • Document the expected Bun version and installation source.
  • In automated environments, provision Bun during image construction rather than at Skill invocation time.
  • Run the converter in a sandbox with minimal filesystem access, restricted environment variables, and limited outbound network access.
  • Periodically review and update the pinned runtime through a controlled dependency-update process.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `scripts/main.ts` | Main entry point |

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

The skill allows execution via npx -y bun without pinning a specific version or integrity, which can cause the agent to fetch and run whatever package is currently resolved from the registry at runtime. In an agent context, this creates a supply-chain risk because remote code may execute on the user's machine without reproducibility or trust guarantees.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% 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 85)May include surrounding context.

md
Read `$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md` if it exists and look for a `default_theme:` line. Use the value if present; otherwise fall through.

**If theme is resolved from EXTEND.md**: Use it directly, do NOT ask the user.

**If no default found**: use `AskUserQuestion` to confirm a theme from the [Themes](#themes) table below.

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.

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.

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.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file documents that the skill writes /path/to/article.html in the same directory as the input and may create timestamped backup files if an HTML file already exists. While the behavior is described, it is presented as normal output handling rather than a clear user warning about filesystem changes, which is the kind of disclosure SQP-2 expects for actions affecting user data.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency uses a caret range (^0.1.1), which allows automatic resolution to newer releases within the 0.x range permitted by npm semver rules. This increases supply-chain risk because future installs may pull in unreviewed code changes, and this skill processes untrusted Markdown while depending on packages related to parsing and headless Chrome control, making compromised updates more security-sensitive.

Content

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

json
"private": true,
  "type": "module",
  "dependencies": {
    "baoyu-chrome-cdp": "^0.1.1",
    "baoyu-md": "^0.1.1"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency uses a non-exact version (^0.1.1), so installs are not fully reproducible and may silently incorporate upstream changes. Because this package appears to handle Markdown transformation and related rendering features, an unsafe or compromised dependency update could affect parsing, output generation, or downstream execution paths in a way that raises supply-chain exposure.

Content

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

json
"type": "module",
  "dependencies": {
    "baoyu-chrome-cdp": "^0.1.1",
    "baoyu-md": "^0.1.1"
  }
}

Static analysis

No suspicious patterns detected.