Back to skill

Security audit

md-comment

Security checks for vulnerabilities and agentic risk

Overview

This Markdown commenting skill is coherent, but its browser viewer has security weaknesses that could expose reviewed document content or comments.

Install only if you are comfortable reviewing Markdown through a local browser UI. Avoid using it on sensitive or untrusted Markdown until the viewer vendors or pins dependencies, fails closed when sanitization is missing, and builds dynamic UI with safe DOM APIs. Prefer explicit user approval before the agent launches the server or opens a browser.

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

T09 · Insecure Skill Coding Practices

Error
Location
assets/viewer.html:120
Finding

DOM-Based Cross-Site Scripting Through Unsafely Reconstructed Heading Attributes

Content
View full analysis
无标题'; return []; } const usedIds = new Set(); const items = []; let minLevel = 6; headings.forEach((h) => { const level = parseInt(h.tagName.slice(1), 10); if (level < minLevel) minLevel = level; if (!h.id) { let base = slugify(h.textContent); let id = base; let i = 2; while (usedIds.has(id) || document.getElementById(id)) { id = base + "-" + i++; } h.id = id; } usedIds.add(h.id); items.push({ id: h.id, text: h.textContent, level, el: h }); }); list.innerHTML = '
    ' + items.map((it) => { const indent = (it.level - minLevel) * 12; return `
  • ${escapeHtml(it.text)}
  • `; }).join("") + '
'; ``` ### Technical Analysis The application initially parses and sanitizes Markdown, then extracts heading identifiers from the resulting DOM. However, `buildOutline()` subsequently interpolates each heading's `id` into the `href` and `data-id` attributes of a new HTML string. Only the visible heading text is passed through `escapeHtml()`. The identifier is inserted without attribute encoding or strict validation: ```javascript href="#${it.id}" data-id="${it.id}" ``` An identifier containing quotes or other attribute-breaking characters can terminate the intended attribute and introduce additional HTML attributes or elements when the generated string is assigned to `list.innerHTML`. This creates a secondary injection sink after the initial sanitization step. Sanitizing one DOM repr ...[truncated 1838 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
assets/viewer.html:92
Finding

Untrusted Markdown Is Rendered Without Sanitization When DOMPurify Is Unavailable

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
assets/viewer.html:6
Finding

Mutable Third-Party JavaScript Is Loaded Without Version Integrity Verification

Content
View full analysis
``` ### Technical Analysis The viewer executes JavaScript obtained from a third-party CDN every time the page is loaded with network access. The `marked` dependency is not pinned to a version. The DOMPurify dependency is pinned only to major version `3`, allowing the delivered implementation to change over time. Neither resource uses Subresource Integrity. Consequently, the reviewed package does not fully determine the code that executes during the Skill workflow. A compromised package release, CDN account, dependency distribution path, or mutable package alias could result in arbitrary third-party JavaScript executing in the viewer. That script runs before the main application and has access to the page's embedded data and browser APIs. The same remote references are retained in generated static HTML, so opening a static review file can also retrieve executable code from the external CDN. ### Attack Path 1. An attacker compromises an applicable package distribution path, CDN response, or mutable package version referenced by the viewer. 2. A user runs the Skill or opens a generated static viewer while network access is available. 3. The browser downloads the modified script from jsDelivr. 4. Because there is no integrity hash, the browser accepts and executes the modified content. 5. The script accesses `window.__DATA__`, including the reviewed Markdown content and file metadata. 6. The script can manipulate rendered content, observe review comments, alter submissions, or transmit accessible information externally. This path requires compromise or malicious modification of the remote dependency del ...[truncated 735 chars]
Remediation
View remediation
``` If CDN delivery must be retained: 1. Pin each dependency to an exact, immutable version. 2. Add a verified Subresource Integrity hash and `crossorigin="anonymous"`: ```html ``` 3. Record exact versions and hashes in project dependency documentation. 4. Establish a controlled process for dependency upgrades and security review. 5. Apply a restrictive Content Security Policy limiting script sources and outbound connections. 6. Ensure generated static HTML is genuinely self-contained rather than dependent on mutable remote scripts. 7. Test the viewer with network access disabled to verify that all security-critical rendering components remain available locally. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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 (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes a Python script that reads arbitrary Markdown files, writes a JSON output file next to the source, and starts a local HTTP service, but it declares no explicit tool scope or permissions. That mismatch increases the chance an agent can use broader file and network capabilities than reviewers or policy expect, which can lead to unintended file access, overwrites, or local service exposure.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill can be invoked not only by an explicit user command but also whenever the agent decides a Markdown document 'needs targeted human feedback,' which is a broad, subjective trigger. This can cause the agent to open a browser and launch a local server without a clear, current user request, potentially exposing document contents to an unnecessary review flow and surprising the user with side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The instructions state the user clicks a button labeled '完成评论 (Finish)', indicating a Chinese-language UI element, but the document does not mention language selection or that this locale is optional. This can violate language/locale policy if the skill presents a fixed language without user choice or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document declares lang="zh-CN", and the visible UI text throughout the page is also fixed in Chinese. For a general-purpose viewer/comment interface, this is a natural-language locale constraint with no user opt-in or stated regional justification in the file.

Content

No source excerpt is available for this finding.