Back to skill

Security audit

ai-market-report

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent market-report generator, but it needs Review because it runs external research workflows, writes persistent report files, and renders unescaped web-derived content into HTML/PDF.

Review this skill before installing. It is not deceptive or destructive, but it sends research queries to external services, depends on a separate Tavily skill, writes report artifacts to fixed workspace paths, and should be fixed to escape all report data and restrict WeasyPrint resource fetching before use with untrusted web content.

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/generate_report.py:104
Finding

Unescaped Markdown Content Enables HTML Injection and Server-Side Resource Requests

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_report.py:104-214, 290-296
Vulnerability Type: Unescaped HTML generation from externally sourced content
Risk Level: Medium

Vulnerable Code

python
def c(s): return re.sub(r"\*\*(.+?)\*\*", r"\1", s).strip()
python
def r_app(rows):
    h=""
    for r in rows:
        if len(r)<5: continue
        n,ra,rv,ca,po=r[0],r[1],r[2],r[3],r[4]
        h+="<tr><td><strong>"+n+"</strong></td><td><span class=\"tg tg-b\">⭐ "+ra+"</span></td><td>"+rv+"</td><td>"+ca+"</td><td>"+po+"</td></tr>\n"
    return h
python
def r_ops(rows):
    h=""
    for r in rows:
        if len(r)<6: continue
        n,mau,rv,vl,dr=r[0],r[1],r[2],r[3],r[4]
        dyn=c(" ".join(r[5:]))[:50]
        cls="wr" if "\u672a\u516c\u5f00" in mau else ""
        h+="<tr><td><strong>"+n+"</strong></td><td class=\""+cls+"\">"+mau+"</td><td>"+rv+"</td><td>"+vl+"</td><td>"+dr+"</td><td style=\"font-size:10px;color:#64748b\">"+dyn+"...</td></tr>\n"
    return h
python
html = build_html(d, template)
with open(html_file, "w", encoding="utf-8") as f:
    f.write(html)

WPHtml(string=html, base_url="/").write_pdf(pdf_file)

Technical Analysis

The report generator parses Markdown containing market data collected from external websites and directly concatenates parsed fields into HTML. The helper function c() only strips Markdown bold markers; it does not apply HTML entity encoding or sanitization.

This unsafe pattern affects application names, ratings, categories, product descriptions, operational metrics, market descriptions, events, opportunities, risks, personas, and strategy text. Consequently, HTML elements supplied throu ...[truncated 2932 chars]

Remediation
View remediation

Remediation Suggestions

  1. Apply contextual HTML escaping to every untrusted scalar value before inserting it into markup:

    python
    from html import escape
    
    def safe_text(value):
        return escape(str(value), quote=True)
    

    Use safe_text() for every Markdown-derived field, including names, metrics, descriptions, events, opportunities, risks, personas, and strategy entries.

  2. Replace manual string concatenation with an auto-escaping template engine such as Jinja2:

    python
    from jinja2 import Environment, FileSystemLoader, select_autoescape
    
    env = Environment(
        loader=FileSystemLoader(template_directory),
        autoescape=select_autoescape(["html", "xml"]),
    )
    

    Only mark fixed, application-generated components as safe after their constituent values have been escaped.

  3. If limited inline formatting is required, parse and sanitize it with a strict allowlist. Reject resource-bearing and layout-breaking elements, including img, link, style, iframe, object, embed, and SVG-related elements. Remove URL-bearing attributes unless explicitly required.

  4. Configure a custom WeasyPrint url_fetcher that:

    • Allows only explicitly approved HTTPS hosts.
    • Rejects file:, ftp:, data:, and other unnecessary schemes.
    • Rejects loopback, private, link-local, multicast, and reserved IP ranges.
    • Revalidates the resolved address after DNS resolution and redirects.
    • Applies strict response-size and timeout limits.
  5. Bundle required fonts locally and remove remote stylesheet imports so normal report generation does not require external network access.

  6. Run PDF generation in a sandbox with no access to credentials or sensitive files and with outbound network access disabled unless strictly necessary.

  7. Add regression tests using payloads in every parsed field. Verify that angle brackets are emitted as entities and that PDF generation prod ...[truncated 36 chars]

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The code chunk is a report renderer/generator from preexisting Markdown input, not a full market-research automation pipeline. Its core behavior is: read a markdown file, parse specific headings/tables, populate an HTML template, and export HTML/PDF. That aligns only with the final rendering portion of the declared description. The description materially overstates the implemented capabilities by claiming upstream data acquisition and research-generation steps that are absent from this code. No suspicious undeclared external access or unrelated behavior is evident, but there is still a description-behavior mismatch because the declared primary purpose is end-to-end automation while the actual code is only the formatting/rendering stage.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill performs file read/write operations and directs creation of multiple report artifacts, but it declares no explicit tool scope or permissions boundary. That creates a governance gap: the agent may gain broader-than-expected filesystem capabilities, making it harder to enforce least privilege and increasing the chance of unintended file access or overwrites.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad enough to activate on generic market-report requests, which can cause the agent to invoke this skill outside its intended narrow domain. Overbroad invocation increases the risk of unnecessary external data collection, file creation, and execution of the rendering workflow when the user did not clearly request this specific behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to create Markdown, HTML, and PDF files and copy them into the workspace, but it gives no user-facing notice or consent checkpoint about filesystem writes. This can lead to unexpected persistence of artifacts, accidental overwrites, and confusion about where sensitive or proprietary report data is being stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill directs use of external APIs and web search to collect market data but omits any privacy or data-transfer warning. If user-provided product names, business interests, or research topics are sent to third-party services without clear disclosure, confidential intent or sensitive context may be exposed externally.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · references/data_collection.md (reported line 63)May include surrounding context.

bash
# 读取 tavily skill
读取 /root/.openclaw/workspace/skills/tavily-search/SKILL.md

# 深度搜索(推荐,覆盖网页+新闻+论坛)
node /root/.openclaw/workspace/skills/tavily-search/scripts/search.mjs "QUERY" --deep

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The HTML root sets lang="zh-CN", and the visible report content is also written entirely in Chinese. For a general market-report template, this imposes a specific language/locale without any indication that users can choose another language, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

A language policy issue exists when a skill mandates a specific language without giving the user a choice. This file's operational instructions and output expectations are entirely in Chinese, with no indication that another language may be used if the user prefers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to query external services (Apple iTunes API and Tavily) and retrieve third-party content, but it does not require any user-facing notice or consent before transmitting search terms and fetching URLs. This can expose user-supplied research targets or sensitive prompts to external providers and may surprise users who expected local-only processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instructions direct the agent to create Markdown, HTML, and PDF files in workspace paths and then copy artifacts into a user-accessible working directory, but they do not warn about file creation or possible overwrite/collision behavior. This can lead to unexpected persistence of generated artifacts and accidental replacement of existing files if timestamps or paths collide.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.