Back to skill

Security audit

Pans Case Writer

Security checks for vulnerabilities and agentic risk

Overview

The skill is a straightforward Chinese case-study generator, but its PDF export can resolve untrusted local or network resources and its HTML export preserves raw markup from input files.

Install only if you will use it on trusted case-study Markdown or can sandbox exports. Be especially careful with PDF export from files supplied by others, because embedded images or raw HTML may trigger network or local resource access during rendering. HTML export should also be treated as unsafe for untrusted input unless the Markdown is sanitized first.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/case.py:81
Finding

Stored HTML Injection in Markdown-to-HTML Export

Content
View full analysis
\1", html, flags=re.MULTILINE) html = re.sub(r"^## (.+)$", r"

\1

", html, flags=re.MULTILINE) html = re.sub(r"^# (.+)$", r"

\1

", html, flags=re.MULTILINE) lines = html.split("\n") result = [] in_ul = False for line in lines: line = line.strip() if not line: if in_ul: result.append("") in_ul = False continue if line.startswith("") in_ul = False result.append(line) elif line.startswith("-"): if not in_ul: result.append("
    ") in_ul = True result.append(f"
  • {line[1:].strip()}
  • ") else: if in_ul: result.append("
") in_ul = False result.append(f"

{line}

") if in_ul: result.append("") return "\n".join(result) def export_html(md_path, html_path): with open(md_path, encoding="utf-8") as f: md = f.read() body = md_to_html(md) html = f""" Case Study body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; max-width: 800px; margin: 60px auto; padding: 0 20px; color: #1a1a1a; line-height: 1.8; }} h1 {{ border-bottom: 3px solid #2563eb; padding-bottom: 10px; color: #1e3a8a; }} h2 {{ margin-top: 40px; color: #1e40af; border-left: 4px solid #3b82f6; padding-left: 12px; }} p {{ margin: 12px 0; }} ...[truncated 2082 chars]
Remediation
View remediation
`, event-handler attributes, malformed tags, SVG payloads, and `javascript:` links. 5. Consider applying a restrictive Content Security Policy to generated documents as defense in depth, while not treating it as a replacement for output encoding and sanitization. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/case.py:142
Finding

Unrestricted External and Local Resource Resolution During PDF Export

Content
View full analysis
body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; max-width: 800px; margin: 60px auto; padding: 0 20px; color: #1a1a1a; line-height: 1.8; }} h1 {{ border-bottom: 3px solid #2563eb; padding-bottom: 10px; color: #1e3a8a; }} h2 {{ margin-top: 40px; color: #1e40af; border-left: 4px solid #3b82f6; padding-left: 12px; }} {body_html}""" WPHTML(string=html).write_pdf(pdf_path) ``` ### Technical Analysis The PDF export path converts attacker-controlled Markdown to HTML and passes it directly to WeasyPrint. No sanitization is applied to raw HTML, and no restrictive WeasyPrint URL fetcher is configured. HTML-to-PDF engines may retrieve resources referenced by elements and styles, including images, stylesheets, fonts, and other URLs. Consequently, crafted Markdown or embedded raw HTML can direct the renderer to make requests to attacker-selected URLs, loopback services, link-local metadata endpoints, or private-network addresses. Depending on renderer behavior and process permissions, `file:` resources may also allow local files to be read and incorporated into the generated document. Unlike browser-side script injection, exploitation does not require JavaScript execution. Resource loading occurs while the PDF is being generat ...[truncated 1449 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill advertises file-writing/export behavior (Markdown/PDF/HTML generation) but does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization gap where the runtime may permit broader filesystem write behavior than intended, increasing the risk of overwriting files or writing sensitive content to unintended locations if the implementation is unsafe.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This JSON case file presents all user-facing natural-language content exclusively in Chinese, including the title, background, solution, and testimonial, with no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking context. Under the policy, hard-coding a specific language without user opt-in can constitute a locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code presents the skill description and all interaction text in Chinese, and later also hard-codes zh-CN in generated HTML. The policy requires language or locale choice unless the constraint is explicitly justified; this file provides no opt-in or documented region-specific limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The HTML export sets <html lang="zh-CN">, and the PDF export similarly embeds zh-CN in its generated HTML. Forcing a specific locale in outputs without allowing user selection or explaining the restriction is a natural-language policy violation.

Content

No source excerpt is available for this finding.