Back to skill

Security audit

amazon-sorftime-research-category-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs the advertised category analysis, but it needs review because it automatically uses a local API key, sends it in URLs, and can generate unsafe HTML reports from external data.

Review before installing. Use a dedicated low-privilege Sorftime API key, avoid storing unrelated secrets in the .mcp.json visible to this skill, and be cautious opening or sharing generated dashboard.html files until the HTML escaping and CDN dependency are fixed.

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

Error
Location
scripts/generate_reports.py:585
Finding
Stored JavaScript Injection in Generated HTML Dashboards<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_reports.py:585-592`; `assets/dashboard_template.html:569-617` **Vulnerability Type**: Stored JavaScript injection / DOM-based cross-site scripting **Risk Level**: High ### Vulnerable Code ```python content = content.replace('{{SALES_TREND_DATA}}', json.dumps(chart_data['sales_trend'], ensure_ascii=False)) content = content.replace('{{PRICE_TREND_DATA}}', json.dumps(chart_data['price_trend'], ensure_ascii=False)) content = content.replace('{{PRICE_DIST_DATA}}', json.dumps(chart_data['price_dist'], ensure_ascii=False)) content = content.replace('{{RATING_DIST_DATA}}', json.dumps(chart_data['rating_dist'], ensure_ascii=False)) content = content.replace('{{BRAND_SHARE_DATA}}', json.dumps(chart_data['brand_share'], ensure_ascii=False)) content = content.replace('{{SELLER_SOURCE_DATA}}', json.dumps(chart_data['seller_source'], ensure_ascii=False)) content = content.replace('{{BRAND_RATING_TREND_DATA}}', json.dumps(chart_data['brand_rating_trend'], ensure_ascii=False)) content = content.replace('{{TOP50_PRODUCTS}}', json.dumps(chart_data['top50_products'], ensure_ascii=False)) ``` The resulting data is inserted into an executable script block and later passed to `innerHTML`: ```javascript const top50Products = {{TOP50_PRODUCTS}}; const tableBody = document.getElementById('top50TableBody'); top50Products.forEach((product, index) => { const row = tableBody.insertRow(); row.innerHTML = ` <td>${index + 1}</td> <td>${product.asin}</td> <td style="text-align:left;">${product.title}</td> <td>${product.brand}</td> <td>$${product.price}</td> <td>${product.rating}</td> <td>${product.sales}</td> <td>${product.marketShare}%</td> `; }); ``` ### Technical Analysis Product titles, brands, ASINs, seller-source values, and trend fields can originate from the external Sorftime API or from a user-supplied JSON file. These fields are se ...[truncated 2114 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not use `innerHTML` for API-derived values. Construct each cell separately and assign content through `textContent`: ```javascript const cell = row.insertCell(); cell.textContent = String(product.title ?? ''); ``` 2. Store serialized report data in a non-executable JSON element: ```html <script id="report-data" type="application/json">...</script> ``` Parse it with: ```javascript const reportData = JSON.parse( document.getElementById('report-data').textContent ); ``` 3. Before embedding JSON into HTML, escape at least `<`, `>`, `&`, U+2028, and U+2029. In particular, encode `<` as `\u003c` so `</script>` cannot terminate the element. 4. HTML-escape category names, site values, and all other variables inserted into normal HTML contexts. 5. Add a restrictive Content Security Policy that blocks inline event handlers and limits script sources. Prefer external, locally hosted scripts with nonce- or hash-based authorization. 6. Add regression tests using values containing `</script>`, `<img src=x onerror=alert(1)>`, quotation marks, backticks, and Unicode line separators. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (59)

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding
描述与代码存在实质性不匹配。虽然代码确实涉及“类目统计提取”和“五维评分”,与选品分析主题部分相关,但其实际职责更窄:它只是一个离线后处理脚本,从已有的 Sorftime 响应文件中提取固定字段并计算分数。声明中的核心能力——根据用户请求触发、执行完整市场调研、分析多个品类/TopN、输出 Markdown 报告——在该代码中均未出现。代码也没有网络访问、亚马逊数据抓取、报告生成或技能触发处理逻辑。因此这不是仅仅实现细节层面的差异,而是功能范围和主要用途明显缩小,且包含未声明的数据源依赖。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
代码的核心功能是读取一个文件、提取产品字段(ASIN、标题、价格、月销量、评分、品牌等)、展示 Top 产品,并计算一些基础统计值。这与声明中的“亚马逊品类自动化选品分析技能”存在明显差距:声明强调的是面向用户请求的品类市场调研、五维评分模型、以及 Markdown 报告生成,而代码并未实现这些关键能力。虽然“支持配置分析数量”与代码中的 limit 参数有部分对应,且对提取后的产品进行了简单统计,但这只属于辅助数据处理,不足以支撑声明的主要用途。因此属于描述与实际行为的实质性不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
声明描述的是一个面向亚马逊品类选品与市场调研的分析技能,但代码实际仅实现了本地 JSON 编码异常修复工具。其核心功能是检测字符串中的乱码模式、尝试 latin-1/utf-8 转码修复,并对指定文件进行备份和覆盖保存。这与声明中的主要目的、能力范围、输入输出形式和触发方式都明显不一致。代码中完全看不到任何亚马逊数据抓取、品类评分、市场分析、Top20 配置处理或 Markdown 报告生成逻辑,因此属于明显的描述-行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
声明描述的是一个面向亚马逊品类选品的分析技能,核心能力应包括品类研究、评分建模、报告生成,以及按用户提出的品类分析需求触发。给出的代码却只实现了关键词SSE响应解析与数据标准化:读取本地文件、提取JSON数组、统一关键词/搜索量字段、保存为keywords.json并打印结果。代码中没有任何品类分析逻辑、五维评分模型、亚马逊市场调研流程、Markdown报告生成或与声明触发词对应的交互处理。因此其主要目的与声明明显不符,属于实质性描述-行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
声明描述的是一个高层次的亚马逊品类分析/选品技能;但提供的代码仅实现了对 category_keywords SSE 响应文件的解析、乱码修复、关键词字段提取、表格打印,以及 txt/json 落盘。代码处理的数据字段主要是“关键词、搜索量、CPC、新品占比”等,属于关键词结果解析,而非完整品类研究报告生成。没有看到任何五维评分模型、市场评估逻辑、报告编排、Markdown 生成、Amazon 类目综合分析流程,触发机制也只是命令行参数而非所声明的技能命令。因此这是明显的描述与实际行为不一致。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
该代码与声明主题相关,都是“品类报告/选品分析”领域,但实现范围明显更窄,且主要功能不同。脚本的核心行为是从现有文件中用正则提取统计数据与产品信息、计算预设评分、打印结果;它没有执行市场调研、没有访问亚马逊或外部数据源、没有实现技能触发入口,也没有生成声明中的 Markdown 报告。虽然五维评分能力与声明部分一致,但整体上这是一个后处理解析工具,而不是完整的“亚马逊品类自动化选品分析技能”。因此应判定为描述与实际行为存在实质性不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
声明描述的是一个面向用户请求的完整“亚马逊品类选品分析”技能,应当执行市场研究、评分、排序并输出分析报告。实际代码仅是一个数据处理辅助脚本:从SSE文本文件中解析趋势字段,抽取日期和值,合并后写入JSON文件。它没有执行品类筛选、评分、调研总结、TopN分析、Markdown报告生成,也没有体现与所述触发词相关的交互逻辑。虽然趋势解析可能是该技能管道中的一个支持步骤,但就该代码块本身而言,其实际行为与声明的主要用途存在明显差异。

Ae1

High
Category
analysis-evasion
Content
| `workflow.py` | 一键执行完整分析流程 | **v4.0** |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| `workflow.py` | 一键执行完整分析流程 | **v4.0** |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

External Script Fetching

High
Category
Supply Chain
Content
**用途**: 根据品类名称查找对应的类目nodeid

```bash
curl -s -X POST "https://mcp.sorftime.com?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"category_name_search","arguments":{"site":"US","searchName":"sofas"}}}'
```
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

MCP Config Access

High
Category
Agent Snooping
Content
def _load_api_key(self) -> str:
        """从配置文件加载 API Key"""
        config_file = Path(".mcp.json")
        if config_file.exists():
            with open(config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
Confidence
90% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The file title and all explanatory content are written in Chinese, which imposes a specific language on readers without indicating any user choice or opt-in. Under the policy, language constraints should either offer a choice or be explicitly justified as locale-specific.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill advertises and documents capabilities requiring environment access, file read/write, shell execution, and outbound network access, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an unnecessary trust gap: an agent may grant broader capabilities than users expect, increasing the chance of unintended file access, command execution, or data transmission during use.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The skill's natural-language triggers are broad enough to match ordinary conversation about category analysis, which can cause unintended activation of a workflow with shell, file, environment, and network capabilities. In an agent setting, ambiguous trigger rules increase the risk of accidental external requests, file generation, or use of sensitive configuration without explicit user intent.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The description and surrounding instructions present the skill as a Chinese-language experience, including generation of a 'Markdown分析报告', without indicating that users may choose another language. This can violate language/locale policy when the skill imposes a specific language by default without opt-in.

External Transmission

Medium
Category
Data Exfiltration
Content
### 调用格式
```bash
curl -s -X POST "https://mcp.sorftime.com?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":N,"method":"tools/call","params":{"name":"TOOL_NAME","arguments":{"amzSite":"US","nodeId":"NODE_ID"}}}'
```
Confidence
91% confidence
Finding
The skill instructs outbound POST requests to a third-party service and places the API key directly in the request URL query string. Query-string secrets are frequently exposed through logs, proxies, shell history, process listings, screenshots, and debugging output, making credential leakage more likely than header- or env-based authentication.

Vague Triggers

Medium
Confidence
90% confidence
Finding
Allowing free-form examples without clear boundaries makes trigger matching ambiguous and can lead the agent to run the skill when the user is merely asking a general question. Because this skill is documented to use external APIs and write local report artifacts, accidental invocation has meaningful security and privacy consequences.

External Transmission

Medium
Category
Data Exfiltration
Content
#### 步骤 1: 搜索类目获取 nodeId

```bash
curl -s -X POST "https://mcp.sorftime.com?key={API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"category_name_search","arguments":{"amzSite":"US","searchName":"品类关键词"}}}'
```
Confidence
91% confidence
Finding
This example again sends requests to an external service with the API key embedded in the URL, increasing the chance of credential disclosure and making outbound data transfer an expected part of the skill's operation. The danger is elevated because the same skill also documents automatic API key retrieval from local configuration, which can couple secret access with external transmission.

External Transmission

Medium
Category
Data Exfiltration
Content
**获取 NodeID 的方法**:
```bash
# 先用大类目搜索,查看返回的子类目列表
curl -s -X POST "https://mcp.sorftime.com?key={API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"category_name_search","arguments":{"amzSite":"US","searchName":"Laptop"}}}'
```
Confidence
90% confidence
Finding
The documented workflow performs external transmission to a third-party endpoint using URL-based API-key authentication. Repeating this pattern across troubleshooting guidance suggests it is standard practice for the skill, increasing the likelihood that users or agents will leak credentials during routine use or debugging.

External Transmission

Medium
Category
Data Exfiltration
Content
5. **测试 API 连接**:
```bash
curl -s -X POST "https://mcp.sorftime.com?key={YOUR_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"category_name_search","arguments":{"amzSite":"US","searchName":"Kitchen"}}}'
```
Confidence
90% confidence
Finding
Even in test commands, embedding secrets in URLs is unsafe because diagnostic invocations are especially likely to be copied into tickets, terminals, CI logs, or chat transcripts. Since this skill is operationally centered around remote API calls, insecure authentication examples create a recurring credential-exposure risk.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The documentation expands the operational scope from Amazon category analysis to TikTok and 1688 platforms, despite the skill being presented as a narrower Amazon-focused capability. Scope expansion matters because it can cause the skill to be invoked in broader contexts, touch additional external systems, and process/send data users did not reasonably expect under the original description.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The HTML document declares `lang="zh-CN"`, and the visible UI text throughout the template is also fixed in Simplified Chinese. This creates a natural-language locale constraint without any indication that users can opt into another language or that the skill is intentionally region-specific.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The template loads ECharts from a third-party CDN at render time, creating a supply-chain and integrity risk. If the CDN asset is tampered with, blocked, or replaced, anyone opening the generated report could execute attacker-controlled JavaScript in the local/browser context; this is more concerning because the skill is expected to generate static analysis reports, not depend on live remote code.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This markdown template is entirely written in Chinese, including the title, section headings, labels, and footer, which indicates the skill produces reports in a fixed language. The policy requires flagging language or locale constraints when the user is not offered a language choice or explicit opt-in, and no such choice is documented in this file.

External Transmission

Medium
Category
Data Exfiltration
Content
### 1. category_name_search - 搜索类目

```bash
curl -s -X POST "https://mcp.sorftime.com?key={API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"category_name_search","arguments":{"amzSite":"US","searchName":"Sofas"}}}'
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.