Back to skill

Security audit

Ppshu Github

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent HTML visualization helper, but its generated local pages have real injection risks that warrant review before installation.

Install only if you are comfortable with it writing persistent HTML artifacts into your current project. Treat generated reports and galleries as active local web pages: avoid opening reports made from untrusted files, use a dedicated output directory when possible, and prefer a patched version that escapes all '<' in embedded JSON, escapes gallery href attributes, and uses stricter Mermaid security settings.

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/diff_report.py:348
Finding

Stored HTML Injection in Generated Diff Reports

Content
View full analysis
` element. The code attempts to prevent premature termination of that element by replacing ``, ``, or `` therefore remain intact. An attacker-controlled compared file can contain a mixed-case closing tag followed by active HTML, for example: ```html ``` When the report is opened, the browser terminates the JSON script element at the mixed-case closing tag and parses the following markup as HTML. The injected event handler then executes in the generated report's browser context. JSON string escaping does not prevent this issue because the HTML parser identifies the closing script tag before JavaScript or JSON parsing semantics are applied. ### Attack Path 1. An attacker creates or modifies a source, configuration, text, or HTML file that will be included in a diff. 2. The attacker inserts a mixed-case closing script tag followed by executable HTML. 3. A user invokes `scripts/diff_report.py` with that file as either the old or new input. 4. The generator ser ...[truncated 931 chars]
Remediation
View remediation
` - `` - `` - Closing-tag text split across compared lines - Injected tags with event handlers 5. Open generated reports in a sandboxed preview context where available. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/save_html.py:104
Finding

Stored Attribute Injection in the Generated Gallery

Content
View full analysis
{serial} · {_html.escape(desc)}' f'{date}' for serial, desc, fn, date in sorted(items, key=lambda x: x[0]) ) ``` ### Technical Analysis The gallery generator correctly escapes `desc` when inserting it as link text, but inserts `fn` directly into the quoted `href` attribute without HTML attribute escaping. New filenames produced by `kebab()` are constrained to a safe character set. However, `build_index()` scans every pre-existing filename matching this broad expression: ```python r"^(\d{3})-(.+)\.html$" ``` On filesystems that allow quotation marks in filenames, an attacker can place a specially named HTML file in the target directory. A filename containing a quotation mark can terminate the `href` value and introduce a new event-handler attribute. For example, a filename shaped like the following can inject an `onclick` attribute: ```text 001-x" onclick="alert(document.domain)" x=".html ``` Because only the visible description is escaped, the generated `href` remains syntactically unsafe. ### Attack Path 1. An attacker gains the ability to add a file to the project-controlled `.ppshu` directory or another directory selected through `--dir` or `PPSHU_DIR`. 2. The attacker creates a filename matching the gallery pattern while including quotation marks and an event-handler attribute. 3. The user runs `save_html.py` to save any diagram. 4. `build_index()` scans the hostile filename and interpolates it directly into the gallery's `href` attribute. 5. The user opens the regenerated `index.html`. 6. The injected event handler executes when its triggering interaction occurs, such as clicking the malicious gallery entry. ### Impact Assessment Successful ...[truncated 623 chars]
Remediation
View remediation
' f'{serial} · {_html.escape(desc)}' f'{date}' for serial, desc, fn, date in sorted(items, key=lambda x: x[0]) ) ``` Additional hardening should include: 1. URL-encode path components with `urllib.parse.quote()` before inserting them into `href`. 2. Restrict accepted gallery filenames to the same character policy enforced by `kebab()`, rather than accepting arbitrary text through `(.+)`. 3. Reject filenames containing control characters, quotation marks, angle brackets, or unexpected Unicode separators. 4. Resolve and validate paths to ensure each gallery item remains inside the intended directory. 5. Add tests using filenames containing `"`, `'`, `<`, `>`, `&`, whitespace, and event-handler-like text. 6. Consider generating gallery elements with DOM APIs and assigning links through the `href` property rather than composing HTML strings. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description claims a visualization skill focused on producing single-file HTML drawings and interactive prototypes, with explicit file organization behavior under a .ppshu directory. The actual code is a minified JavaScript asset for mathematical typesetting/rendering, likely part of a library such as KaTeX. It defines parsing, macro expansion, math environments, delimiters, accents, fractions, arrays, links, styling, and HTML/MathML output for math expressions. This is a materially different primary purpose from the declared skill. There is also no visible code handling filesystem organization, numbered HTML output, or diagram/prototype generation. Therefore the declared description does not accurately represent the supplied code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

声明描述的核心能力是:为用户创建单文件 HTML 可视化/交互原型,并把这些 HTML 文件按序号存放到 .ppshu 目录。给出的代码却是 mermaid.min.js 的内部实现片段,主要功能是词法/语法解析 Mermaid 文本、维护图表数据、并渲染图表(例如饼图、象限图、XY 图)。这是可视化底层依赖的一部分,但与“生成单文件 HTML 文件并进行目录管理”这一主要目的不一致。虽然两者都和可视化有关,代码没有体现声明中的关键工作流(HTML 文件生成、保存到 .ppshu、统一编号管理、可删除目录管理),反而表现出未声明的具体能力:Mermaid DSL 解析与 SVG/图形渲染。因此应判定为描述与实际行为存在实质性不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

虽然该代码最终也会生成单文件 HTML,且页面带有一定交互性,但其实际用途非常具体:比较两份文件并生成可验证的 diff 审查报告。这与声明中的“通用画图、讲解概念、交互式 UI 原型、任何把东西画出来的需求”并不一致,属于主要目的明显不同。尤其是声明中关于 .ppshu 目录集中保存和编号管理,在该代码里完全没有实现;代码反而实现了本地文件读取、差异分析和 SHA-256 校验等更偏审查报告的能力。因此描述不能准确代表该代码块的实际行为。

Content

No source excerpt is available for this finding.

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 · assets/mermaid.min.js (reported line 12)May include surrounding context.

js
;var d=typeof s;return(d=="number"?w9(u)&&FX(s,u.length):d=="string"&&s in u)?pD(u[s],i):!1}function gRt(i){return RX(function(s,u){var d=-1,p=u.length,v=p>1?u[p-1]:void 0,b=p>2?u[2]:void 0;for(v=i.length>3&&typeof v=="function"?(p--,v):void 0,b&&QF(u[0],u[1],b)&&(v=p<3?void 0:v,p=1),s=Object(s);++d<p;){var y=u[d];y&&i(s,y,d,v)}return s})}var pRt=gRt(function(i,s,u){oje(i,s,u)});const jX=pRt,hje="​",bRt={curveBasis:FF,curveBasisClosed:LNt,curveBasisOpen:MNt,curveBumpX:_Nt,curveBumpY:ANt,curveBundle:DNt,curveCardinalClosed:ONt,curveCardinalOpen:NNt,curveCardinal:INt,curveCatmullRomClosed:BNt,curveCatmullRomOpen:FNt,curveCatmullRom:PNt,curveLinear:kp,curveLinearClosed:RNt,curveMonotoneX:jNt,curveMonotoneY:$Nt,curveNatural:zNt,curveStep:qNt,curveStepAfter:VNt,curveStepBefore:HNt},mRt=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,vRt=function(i,s){const u=fje(i,/(?:init\b)|(?:initialize\b)/);let d={};if(Array.isArray(u)){const b=u.map(y=>y.args);SX(b),d=i

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README says users can invoke the skill by saying broad phrases like “画个登录流程图”, “用图对比单体架构和微服务”, and “做个能填表单、能点的原型”, but it does not define a bounded trigger set or exclusion conditions. These phrases overlap with ordinary conversational requests and could cause unintended activation because the scope and limits of invocation are not explicitly described.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documentation instructs the agent to read/write files, invoke Python scripts, use shell commands, and optionally use environment variables, but it does not declare any tool scope or permission boundaries. That creates an implicit over-privilege problem: an orchestrator or reviewer cannot tell from the manifest what capabilities the skill expects, increasing the chance of unintended file modification or command execution in user projects.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger conditions are very broad, including almost any request to 'show' or 'draw' something, which increases the chance the skill activates in ordinary conversations without clear user consent to create files or run tooling. In this skill's context, overbroad activation is more dangerous because the workflow proceeds to generate HTML and write artifacts into the current project.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill states that it will create a .ppshu directory, generate numbered HTML files, and rebuild an index in the current project, but it does not prominently warn that it modifies the working directory. This can lead to surprising repository changes, accidental inclusion in commits, or unintended alteration of sensitive project workspaces.

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.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description says the skill is automatically applied for broad classes of user intent, including visualization, diagrams, charts, state machines, and interactive prototypes, without clearly scoped limits. This creates prompt-routing ambiguity and can cause the agent to invoke the skill in situations where the user did not intend HTML generation or interactive content creation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list contains broad everyday phrases such as '流程图', '架构图', and '可视化', which can cause the skill to activate in normal conversation without an explicit user request to invoke this specific tool. Over-broad activation increases the chance of unintended file creation or workflow changes, especially because the skill is designed to automatically generate HTML artifacts in the project workspace.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill explicitly directs the agent to create a .ppshu/ directory inside the current project, write numbered HTML files, and regenerate an index.html gallery, but it does not require explicit user consent before modifying the workspace. In an agent setting, silent filesystem writes can violate user expectations, alter repositories, and create persistence/artifacts that may later be committed or trusted as project content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The title and the embedded examples/instructions indicate the skill is authored to produce Chinese-language output, and the flowchart example uses Chinese node labels. The file does not offer an opt-in or alternative language choice, which can violate language/locale policy when a skill forces a specific language by default.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The template initializes Mermaid with securityLevel: 'loose', which weakens Mermaid's built-in protections and can allow raw HTML or more permissive rendering behavior from diagram content. In a skill designed to generate visualizations from user-driven content, this increases the risk that untrusted Mermaid code embedded into {{MERMAID_CODE}} could produce script-capable or unsafe DOM content, undermining the claim of a tightly safe offline renderer.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language documentation and generated HTML are fixed to Chinese, including the page language declaration and all user-facing labels, with no indication that users can choose another language. This is a locale-policy concern because the skill imposes a specific language experience rather than offering opt-in or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Tainted flow: 'out_path' from os.environ.get (line 168, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/save_html.py (reported line 169)May include surrounding context.

python
content = sys.stdin.read()

    out_path = os.path.join(directory, filename)
    with open(out_path, "w", encoding="utf-8") as f:
        f.write(content)

    # 流程图类会引用 ./mermaid.min.js,这里自动把打包的库补到同目录,离线可用

Tainted flow: 'directory' from os.environ.get (line 153, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/save_html.py (reported line 175)May include surrounding context.

python
# 流程图类会引用 ./mermaid.min.js,这里自动把打包的库补到同目录,离线可用
    maybe_copy_mermaid(directory, content)

    with open(os.path.join(directory, "index.html"), "w", encoding="utf-8") as f:
        f.write(build_index(directory))

    print(os.path.abspath(out_path))

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

L82 写明“描述尽量用中文或英文短词”,对输出语言形成了限定或偏好,但没有说明这是用户可选项,也没有给出其他语言可接受的选择。这可能构成未经用户明确选择的语言/locale 偏好约束。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language fields, including the name, description, tags, and triggers, are entirely Chinese, which implies a language-specific experience. There is no indication that users can opt into another language or that the Chinese-only behavior is an intentional, documented locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The note says descriptions should preferably use Chinese or English short words, which imposes a language preference in natural-language instructions. There is no opt-in or explanation that other languages are equally acceptable, so this may conflict with a language/locale choice policy.

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", which hard-codes a specific language/locale. Under the policy, forcing a locale without user opt-in or documented regional justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The generated HTML sets lang="zh-CN", and the UI text throughout the file is Chinese-only, which imposes a specific language/locale on users by default. Under the policy, language constraints should be optional, user-selectable, or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This script creates a directory and writes HTML files plus a regenerated index.html, but the executing code provides no runtime confirmation, prompt, or user-facing log message describing those write operations. Although the module docstring documents the behavior, the code path itself performs multiple filesystem modifications silently except for printing the final saved path.

Content

No source excerpt is available for this finding.