Back to skill

Security audit

md-to-html

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does the advertised Markdown-to-HTML conversion, but generated pages can carry active scripts or make attacker-chosen browser requests if the Markdown input is untrusted.

Review before installing. Use this only for Markdown files you trust, or inspect/sanitize the generated HTML before opening it in a browser. A safer version should strip raw active HTML, remove Prism file-highlight/data-src support, use Mermaid strict or sandboxed mode, and add a restrictive Content Security Policy.

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

Error
Location
scripts/md2html.py:812
Finding

Untrusted Markdown Can Inject Executable HTML and JavaScript

Content
View full analysis
{content_html}
``` Mermaid is also explicitly configured with a permissive security level: ```javascript mermaid.initialize({ startOnLoad: false, theme: 'default', securityLevel: 'loose', suppressErrorRendering: true }); ``` ### Technical Analysis Python-Markdown preserves raw HTML by default. The converter does not sanitize the output of `md.convert()` before interpolating it into the final document. Consequently, raw elements and attributes supplied through the Markdown input can become active browser content. Potential payload classes include: - `
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
lib/prism.min.js:1
Finding

Bundled Prism Plugin Allows Attacker-Selected Network Requests

Content
View full analysis
` elements containing `data-src`: ```javascript c="pre[data-src]:not(["+(u="data-src-status")+'="loaded"]):not(['+u+'="'+(g="loading")+'"])' ``` It reads the attacker-controlled attribute and sends an XMLHttpRequest: ```javascript t=o.getAttribute("data-src") ``` ```javascript (i=new XMLHttpRequest).open("GET",n,!0), i.onreadystatechange=function(){ 4==i.readyState&&( i.status<400&&i.responseText ? a(i.responseText) : 400<=i.status ? s("✖ Error "+i.status+" while fetching file: "+i.statusText) : s("✖ Error: File does not exist or is empty") ) }, i.send(null) ``` The converter embeds this Prism build: ```python prism_core = read_lib_file('prism.min.js') if prism_core: resources['js'] += f'\n' ``` The generated page then invokes Prism over the document: ```javascript if (window.Prism) Prism.highlightAll(); ``` ### Technical Analysis Prism's File Highlight plugin is designed to load source code referenced by a `
text
` element. This project only declares syntax highlighting for code already contained in Markdown, so external file retrieval is not necessary for the Skill's functionality.

Because raw HTML from Markdown is not sanitized, an attacker can introduce a `
text
` element with an arbitrary `data-src` value. When the generated page calls `Prism.highlightAll()`, the plugin finds that element and initiates an XMLHttpRequest.

This directly contradicts the Skill's documented claim that generated pages are fully offline and require no network connection.


...[truncated 1593 chars]
Remediation
View remediation
` values using HTTP, HTTPS, local paths, and loopback addresses. Confirm that opening the output produces no XMLHttpRequest or Fetch traffic. 6. **Verify bundled-library composition** Record exact library versions and build options, and periodically rebuild the frontend bundle from reviewed upstream sources with unnecessary plugins excluded. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

该代码片段的核心功能是对已有 HTML/DOM 内容中的 LaTeX 数学表达式进行自动识别和渲染,这是一个前端数学排版辅助库。声明描述的技能则是“将 Markdown 转换为带左侧固定目录的 HTML 阅读页面”,应包含 Markdown 解析、HTML 文档生成、目录提取/锚点导航、页面布局等能力。当前代码未体现这些能力,反而体现了一个不同的、较为独立的功能模块。因此代码实际行为与声明用途存在明显且实质性的不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是“Markdown 转带左侧目录的 HTML 笔记生成器”。但提供的代码并未体现 Markdown 解析、目录提取、页面模板生成、左侧固定 TOC、静态网站组装等功能。相反,代码明确属于 KaTeX 数学渲染实现,核心行为是注册和构建 TeX/LaTeX 数学函数、生成 HTML/MathML、渲染箭头/重音/定界符/SVG 等。虽然这类库可能被 Markdown 转 HTML 工具间接依赖,用于渲染文档中的数学公式,但就该代码片段本身而言,其主要目的与声明的技能用途明显不一致,属于实质性描述-行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个 Markdown 到 HTML 的笔记转换工具,重点能力应包括 Markdown 解析、HTML 页面生成、左侧固定目录/大纲构建、文档导航或静态站点输出。但实际代码是 katex.min.js 的片段,内容集中在 defineFunction/defineEnvironment、数学分组构建、分式/矩阵/括号/运算符/链接/图片/HTML 扩展等 KaTeX 功能实现。这与 Markdown 转换、目录提取、页面模板拼装没有直接关系。虽然该库可能可作为 Markdown 渲染流程中的一个辅助依赖,用于公式显示,但就此代码片段本身而言,其主要用途与声明的技能目标明显不符,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

代码内容明显属于 KaTeX 数学公式渲染引擎的一部分,包含 sqrt、styling、supsub、symbol spacing、text、underline、verb、Lexer、Namespace、macros、MacroExpander、Parser 等模块。这些功能的核心用途是解析 TeX/LaTeX 数学表达式并输出 HTML/MathML,而不是把 Markdown 笔记转换成带左侧目录的 HTML 页面。虽然在最终 Markdown 转 HTML 的系统中,KaTeX 可能作为配套依赖存在,但当前给出的代码块本身并未展示 Markdown 解析、标题提取、目录生成、HTML 模板拼装、左侧固定目录布局等声明中的关键能力,因此描述与实际代码行为存在显著不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

代码内容明显属于 katex.min.js,即 KaTeX 数学公式渲染库。片段实现了解析符号、处理重音与连字、生成解析树,以及 render/renderToString/renderToHTMLTree 等函数。这些能力与声明的“Markdown 转 HTML 并生成左侧固定目录大纲”没有直接对应关系。虽然 Markdown 转 HTML 工具可能会依赖 KaTeX 作为公式渲染的支持组件,但就当前提供的代码片段本身来看,其实际行为是数学公式渲染,而不是 Markdown 转换或目录导航页面生成,因此属于描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

从代码内容看,这不是实现“Markdown 转换为带目录 HTML”的核心逻辑,而是一个压缩后的 Mermaid 前端库及其依赖集合。代码包含日志、URL 清洗、DOM 选择与操作、SVG 路径、颜色插值、动画过渡、坐标轴、格式化、fetch 文本/SVG 解析等通用可视化能力。虽然 Mermaid 可能作为 Markdown 渲染页面中的辅助组件存在,但当前代码块本身并未体现 Markdown 解析、目录提取、HTML 页面模板生成或左侧固定大纲布局等声明中的主要功能。因此,这段代码与声明用途存在明显不匹配,更像是无关或次要依赖库,而非所述技能的核心实现。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个 Markdown→HTML 笔记转换工具,核心能力应至少包括 Markdown 解析、HTML 模板生成、目录/TOC 提取与固定侧边栏渲染。但给出的代码片段来自 lib/mermaid.min.js,内容明显是通用前端库/依赖代码:一部分是 d3 的比例尺、时间、路径和曲线生成,另一部分是 DOMPurify 的 DOM/属性白名单与清洗实现。这些能力可能作为支持性依赖用于渲染 Mermaid 图或清洗输出 HTML,但该片段本身的实际行为与声明的主要目的不一致,且没有看到 Markdown 转换和目录生成的关键逻辑。因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个 Markdown→HTML 转换并生成带左侧目录阅读页面的技能。但该代码片段并未体现 Markdown 解析、HTML 页面生成、目录提取、左侧固定导航或静态站点输出等核心行为。相反,代码主要是 mermaid.min.js 中的通用依赖实现:对 HTML/标签进行消毒和脚本移除、处理图表文本、颜色计算,以及多种 Mermaid 主题和图表默认配置。这些可视为某类文档/图表渲染系统的支撑库,但就该片段本身而言,其实际行为与声明的主要目的存在明显偏离,因此应判定为描述与代码不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是一个 Markdown→HTML 转换工具,重点应在 Markdown 解析、HTML 生成、目录提取/固定侧边栏导航、静态页面包装等。但实际代码是 Mermaid 库的压缩构建片段,包含图表类型探测(如 flowchart、sequence、gantt、mindmap、sankey 等)、配置合并、directive/front matter 解析、SVG 尺寸与可访问性设置、错误图渲染、安全过滤等功能。虽然 Mermaid 可能作为 Markdown 渲染链中的辅助依赖出现,但该代码片段本身并未显示 Markdown 转 HTML 或生成左侧目录的核心行为,因此与声明的主要用途存在明显不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述聚焦于“Markdown 笔记转带目录 HTML 页面”,应主要看到 Markdown 解析、HTML 模板生成、目录提取/左侧导航构建等逻辑。但该代码没有体现 Markdown 转换、目录生成、笔记页面布局等核心行为。相反,它明显属于 Mermaid 图表引擎的一部分:解析 front matter、处理 Mermaid 指令、渲染图表为 SVG、插入 iframe、扫描 .mermaid 节点、支持 C4 语法解析等。这不是对声明功能的辅助实现细节,而是一个 materially different 的主要能力,因此存在明显描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个 Markdown→HTML 笔记转换工具,核心能力应包括解析 Markdown、生成 HTML、构建左侧固定目录导航等。但代码片段实际是 Mermaid 压缩库中的一部分:包含 C4 图表数据库操作(如 addDeploymentNode、updateElStyle、updateRelStyle)、图形绘制函数(drawRect、drawBoundary、drawC4Shape、drawRels)、SVG 标记和图标插入、以及图表语法 parser/lexer。没有看到 Markdown 转 HTML、提取标题生成左侧目录、拼接完整 HTML 页面等与声明直接对应的实现。该代码更像是文档渲染依赖中的图表库,主用途与声明明显不一致,因此应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

代码内容明显属于 Mermaid 图表库的压缩/构建产物片段,包含 flowchart 解析器、Graph 类、节点/边操作、子图处理、布局算法,以及在 securityLevel=loose 时为图节点绑定点击回调和链接等功能。这与声明的“Markdown 转换为带目录 HTML 文件”不是同一主要目的。虽然 Mermaid 可能作为 Markdown 渲染 HTML 的配套依赖存在,但当前代码片段本身并未体现 Markdown 解析、HTML 页面生成、左侧固定目录构建等核心行为,反而实现了独立的图表解析和交互能力。因此这是描述与实际代码行为不匹配的情况。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向最终用户的 Markdown→HTML 笔记转换工具,重点能力应包括将 Markdown 生成 HTML,并带左侧固定目录导航。实际代码却是一个大型第三方前端库片段,核心行为集中在图结构布局(节点坐标、边路径、rank/nodesep/ranksep)、SVG/foreignObject 标签渲染、流程图形状与箭头定义、以及 Markdown 解析底层 tokenizer。片段中没有看到实现“读取 Markdown 笔记并输出带左侧固定目录的 HTML 文件”的直接逻辑,也没有目录提取、HTML 页面模板、侧边栏固定目录、静态网页生成等对应功能。虽然 Mermaid 可能作为 Markdown 渲染生态的支持组件,但该代码片段本身与声明用途存在明显主功能不一致,因此应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述的是一个面向用户的 Markdown→HTML 页面转换工具,核心特征应包括 HTML 输出、目录提取、左侧固定导航布局、可能的模板/CSS 注入等。而当前代码片段主要是在做 Markdown 语法解析基础设施:定义 tokenizer、resolver、预处理/后处理、字符引用解码、heading/list/html/link 等语法处理。这可以作为实现该技能的底层依赖,但就所给片段本身而言,并不能证明其实现了声明中的关键功能,反而显示其主要职责是通用 Markdown 解析。由于实际代码行为与声明的主功能存在实质性差异,应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的核心功能是把 Markdown 笔记转换成带左侧目录的 HTML 阅读页面。但提供的代码片段只是 Prism 语法高亮库中针对 JSON 和 webmanifest 的语言定义,属于显示层的辅助功能,且仅限代码高亮。它没有解析 Markdown、没有生成 HTML 页面、没有构建目录导航,也看不出与“笔记转网页”主功能直接对应。因此该代码片段的实际行为与声明用途存在明显不匹配。

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · lib/katex.min.js (reported line 5880)May include surrounding context.

js
const rule = makeSpan(["mspace"], [], options);
  const size = calculateSize(measurement, options);
  rule.style.marginRight = makeEm(size);
  return rule;
}; // Takes font options, and returns the appropriate fontLookup name

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · lib/katex.min.js (reported line 14197)May include surrounding context.

js
const rule = makeSpan(["mspace"], [], options);
  const size = calculateSize(measurement, options);
  rule.style.marginRight = makeEm(size);
  return rule;
}; // Takes font options, and returns the appropriate fontLookup name

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · lib/mermaid.min.js (reported line 10504)May include surrounding context.

js
ect2 = Object(object2);
      while (++index2 < length2) {
        var source = sources[index2];
        if (source) {
          assigner(object2, source, index2, customizer);
        }
      }
      return object2;
    });
  }
  var merge$2 = createAssigner(function(object2, source, srcIndex) {
    baseMerge(object2, source, srcIndex);
  });
  const merge$3 = merge$2;
  const ZERO_WIDTH_SPACE = "​";
  const d3CurveTypes = {
    curveBasis,
    curveBasisClosed,
    curveBasisOpen,
    curveBumpX: bumpX,
    curveBumpY: bumpY,
    curveBundle,
    curveCardinalClosed,
    curveCardinalOpen,
    curveCardinal,
    curveCatmullRomClosed,
    curveCatmullRomOpen,
    curveCatmullRom,
    curveLinear,
    curveLinearClosed,
    curveMonotoneX: monotoneX,
    curveMonotoneY: monotoneY,
    curveNatural,
    curveStep,
    curveStepAfter: stepAfter,
    curveStepBefore: stepBefore
  };
  const directiveWithoutOpen = /\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · lib/prism-bash.min.js (reported line 1)May include surrounding context.

js
!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",a={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},n={bash:a,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-
...[truncated 26 chars]

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill manifest declares executable behavior via Python and implies reading Markdown input and writing HTML output, but it does not constrain tool permissions. In an agent environment, missing explicit scope increases the chance the skill can be invoked with broader shell, file, or even network access than necessary, enlarging the attack surface.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest uses broad trigger phrases like '转换HTML' and '生成HTML笔记' without tighter scope boundaries, which can cause an agent to invoke the skill in contexts beyond simple local Markdown conversion. Overbroad activation increases the risk of unintended file operations or shell execution on inputs the user did not clearly intend this skill to handle.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This bundled KaTeX build exposes trust-gated features such as \href, \url, \includegraphics, and HTML-related commands (for example \htmlClass, \htmlId, \htmlStyle, \htmlData). In a Markdown-to-HTML converter, rendering attacker-controlled Markdown/TeX with these features enabled can introduce XSS, malicious links, external resource loading, tracking, or local-file/network fetch behaviors depending on how KaTeX options are configured upstream.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a local Markdown-to-HTML conversion skill, but this bundled Prism plugin also supports fetching external source files via XMLHttpRequest from elements with data-src attributes. Network retrieval is not an obvious requirement for converting Markdown notes into readable HTML and adds capability beyond the stated purpose.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.obfuscated_code

Potential obfuscated payload detected.

Warn
Code
suspicious.obfuscated_code
Location
lib/mermaid.min.js:24149