Back to skill

Security audit

markdown-export

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward Markdown-to-DOCX/HTML exporter with expected local file and Pandoc usage, but users should treat generated HTML from untrusted Markdown as potentially active content.

Install only if you are comfortable with a local converter that reads Markdown and related template/CSS files and writes output files where directed. Use trusted Markdown for HTML exports, or sanitize/review generated HTML before opening it broadly or publishing it under a trusted origin. Be careful with custom templates, CSS, resource paths, and output paths because they are user-controlled inputs to Pandoc.

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/export_markdown.py:478
Finding

Untrusted Markdown Can Inject Active Content into Generated HTML

Content
View full analysis
str: return ( "markdown+yaml_metadata_block+emoji+footnotes+pipe_tables+grid_tables+task_lists+" "fenced_divs+fenced_code_attributes+raw_attribute+tex_math_dollars" ) ``` Each bundled HTML template then inserts Pandoc's generated body directly into the document. For example, `assets/html/templates/docs-slate.html` contains: ```html $body$ ``` The equivalent output sink appears in all other bundled HTML templates: ```html $body$ ``` ### Technical Analysis Pandoc's `raw_attribute` extension permits input authors to mark fenced content for direct emission in a target format, including HTML. The generated `$body$` is inserted into the final page without an HTML sanitization stage. The bundled templates also do not establish a restrictive Content Security Policy. An attacker controlling Markdown input can therefore submit raw HTML containing active elements such as scripts, event-handler attributes, malicious forms, or iframes. For example, a fenced raw HTML block can be constructed as follows: ```markdown ```{=html} ``` ``` When exported to HTML, the raw block can be preserved in the generated body and executed when a user opens the document ...[truncated 1743 chars]
Remediation
View remediation
str: return ( "markdown+yaml_metadata_block+emoji+footnotes+pipe_tables+grid_tables+task_lists+" "fenced_divs+fenced_code_attributes+tex_math_dollars-raw_html-raw_attribute" ) ``` 2. If raw HTML is a required feature, expose it only through an explicit option such as `--allow-unsafe-html`. Clearly document that the option must not be used with untrusted Markdown. 3. Sanitize Pandoc's HTML output before inserting or publishing it. Use a maintained allowlist sanitizer and reject at least: - `script`, `iframe`, `object`, `embed`, and active form elements. - Inline event handlers such as `onclick` and `onerror`. - Dangerous URL schemes such as `javascript:`. - Unexpected `data:` URLs and external resource references, according to the deployment policy. 4. Add a restrictive Content Security Policy to bundled templates as defense in depth. A baseline for self-contained documents could prohibit scripts and embedded objects: ```html ``` The exact policy should be adjusted if externally linked assets are intentionally supported. 5. Add regression tests that export hostile Markdown and verify that generated HTML does not contain executable scripts, event-handler attributes, dangerous URL schemes, frames, or forms unless an explicitly unsafe mode is selected. 6. Treat Markdown, custom templates, metadata files, and CSS from external users as untrusted input throughout the conversion and publication pipeline. ]]>
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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 (11)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises and demonstrates shell execution plus arbitrary file read/write behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates a governance gap: an agent may invoke filesystem and shell-capable operations without a clearly bounded policy, increasing the risk of unintended command execution, reading sensitive files, or overwriting user data when given malicious or ambiguous inputs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This HTML template sets lang="zh-CN" whenever the lang variable is absent, which imposes a specific locale by default. That is a natural-language policy concern because it forces a language/locale choice without explicit user selection or documented justification.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/export_markdown.py (reported line 596)May include surrounding context.

python
if args.print_command:
            print(" ".join(command), file=sys.stderr)
        completed = subprocess.run(command, check=False)
        if completed.returncode != 0:
            return completed.returncode
        if args.format == "docx":

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The HTML declares lang="zh-CN", which hard-codes a specific language/locale for the document. Under the policy, locale-specific behavior should either offer user choice or be clearly justified as region-specific, and no such opt-in or justification appears in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The body font stack explicitly prioritizes "PingFang SC" and "Noto Sans CJK SC", and the heading stack later includes "Songti SC", which are Simplified Chinese locale-specific fonts. This can be interpreted as a language/locale preference embedded in the skill without any visible opt-in or documented region-specific justification in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The heading font-family includes "Songti SC", which is specific to Simplified Chinese typography. Under the stated policy, embedding a locale-specific preference in natural-language-adjacent configuration can be a policy concern when no user choice or clear regional scope is documented.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The font-family hardcodes locale-specific Chinese font families ("PingFang SC" and "Noto Sans CJK SC") in the default body styling. This is a natural-language/locale choice embedded in the asset without any indication of user opt-in or documentation that the skill is intended only for Simplified Chinese contexts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This HTML template sets lang="zh-CN" as the default whenever the lang variable is absent. That creates a locale-specific default without offering a user choice or documenting that the template is intentionally region-specific, which matches the natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This HTML template hard-codes lang="zh-CN" as the fallback whenever the lang variable is absent. That imposes a specific locale by default, which can violate language/locale policy when the user has not explicitly chosen Chinese and no region-specific justification is present in the file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

When no lang value is provided, the template hard-codes zh-CN as the HTML language. This imposes a specific locale by default rather than offering a neutral fallback or explicit user choice, which can violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This Python file contains a natural-language comment in Chinese ('使用上下文管理器确保临时文件总是被清理') without any indication that the skill supports or offers language choice. The policy for this audit flags language or locale constraints when a specific language is imposed without user opt-in, and this comment introduces such a constraint for maintainers/readers of the skill.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.