Back to skill

Security audit

SaaS辅助决策助手

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent SaaS report generator, but it creates local HTML from user and web-derived content without escaping and requests broad write/edit/shell authority without clear output limits.

Install only if you are comfortable with a Chinese-language SaaS research skill that performs web searches and writes an HTML report. Treat generated reports as untrusted files, especially when they include web-sourced text, and prefer opening them in a constrained browser context until the generator escapes HTML and limits output paths/tools.

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/report_generator.py:105
Finding

Stored HTML and Script Injection in Generated Reports

Content
View full analysis
{text}' ``` Report fields are obtained without sanitization or contextual encoding: ```python def generate_report(data: dict) -> str: name = safe_get(data, "name", "未命名产品") category = safe_get(data, "category", "未指定行业") now = datetime.now().strftime("%Y年%m月%d日 %H:%M") scores = safe_get(data, "scores", {}) score_result = calculate_total_score(scores) market = safe_get(data, "market_demand", {}) user = safe_get(data, "user_profile", {}) pain = safe_get(data, "pain_points", {}) competitors = safe_get(data, "competition", {}) monetization = safe_get(data, "monetization", {}) acquisition = safe_get(data, "acquisition", {}) marketing = safe_get(data, "marketing", {}) cost = safe_get(data, "cost_structure", {}) tech = safe_get(data, "tech_feasibility", {}) risks = safe_get(data, "risks", {}) ``` Those values are then interpolated directly into the generated document: ```python html = f""" SaaS可行性决策报告 - {name} ...

☁️ {name}

{category}
SaaS 产品可行性决策报告
{now}
``` Market research values and list entries are also inserted without escaping: ```python mkt_score = s ...[truncated 4077 chars]
Remediation
View remediation
str: return escape(str(value), quote=True) ``` Use this helper for product names, categories, descriptions, trends, list entries, table cells, persona fields, competitor data, strategies, risks, and all other externally derived values. 2. Do not use encoding alone for values inserted into CSS or other non-text contexts. Validate such values against strict allowlists. Colors should only come from predefined constants. 3. Validate numeric fields before using them in calculations or style attributes: ```python import math def validated_score(value, default=50): try: score = float(value) except (TypeError, ValueError): return default if not math.isfinite(score): return default return max(0, min(100, score)) ``` 4. Prefer a template engine configured with automatic HTML escaping rather than assembling large HTML documents through f-strings. 5. Add a restrictive Content Security Policy to provide defense in depth. For a self-contained report without JavaScript, an appropriate starting point is: ```html ``` 6. Add regression tests covering at least: - `` - `` - SVG event handlers - Iframes and external resource references - Quotes and angle brackets in every report field - Malformed, negative, oversized, infinite, and nonnumeric score values 7. Treat all WebSearch and WebFetch content as untrusted. Preserve it as plain text and never allow source markup to pass directly into the generated report. ]]>
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill name, description, and example invocations are all written as if the skill operates in Chinese, and there is no note that other languages are supported or that Chinese is required for a region-specific reason. This can violate language/locale policy because it imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill requests powerful tools including Write, Edit, and Bash and explicitly instructs writing an HTML report to disk, but it does not declare a restrictive tool scope such as permissions or allowed-tools. That creates an overprivileged skill surface where file-writing behavior is available without clear limitation, increasing the chance of unintended file modification or abuse if the skill is triggered in the wrong context.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The usage section defines triggering as a loose combination of trigger word plus industry and description, but it does not clearly constrain activation boundaries or provide exclusion cases. In context, this is more dangerous because the skill can invoke WebSearch, WebFetch, Bash, and file-writing actions, so ambiguous activation can lead to unintended external access and local artifact generation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The example trigger phrase includes broad natural-language wording such as asking for an evaluation of whether a SaaS idea is feasible, which can overlap with ordinary conversation rather than a clearly delimited command. This raises the risk of accidental invocation, causing the agent to perform web searches, fetch external content, and generate files when the user may only have intended casual discussion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The HTML output hard-codes lang="zh-CN", and the script's user-facing labels and report content are predominantly fixed in Chinese. This imposes a specific language/locale on all users without offering a choice or documenting that the skill is region-specific.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The footer states '数据来源:公开信息搜索', which implies the report content was gathered from public-information search. However, in this file the program only parses JSON arguments, generates HTML, and writes it to disk; there is no search, crawling, or retrieval logic anywhere in the implementation. This is an active documentation/content claim that contradicts the code's actual behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.