Back to skill

Security audit

Amazon产品研究员

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Amazon product research skill, but it needs Review because it can send API keys and research data to arbitrary LLM endpoints and auto-opens generated HTML built from untrusted content.

Install only if you are comfortable sending product ideas, review text, and LLM API credentials to the configured provider. Use a provider endpoint you trust, avoid plaintext or unknown api_base values, prefer mock mode for demos, and be cautious opening generated reports from live marketplace data until the HTML escaping issue is fixed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_report.py:65
Finding
Stored HTML and JavaScript Injection in Generated Reports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_report.py:65-74`, `scripts/generate_report.py:116-126`, and `scripts/generate_report.py:324-338, 401-587` **Vulnerability Type**: Stored cross-site scripting through unsafe HTML generation **Risk Level**: High ### Vulnerable Code ```python data_json = json.dumps({ "query": query, "products": products[:10], "total_reviews": total_reviews, "avg_rating": avg_rating, "rating_dist": _rating_distribution(ratings), "sentiment_dist": sentiments, "keyword_data": keyword_data, "voc_data": _simplify_voc(voc_data), "competitor_data": _simplify_competitor(competitor_data), "opportunity_data": opportunity_data, }, ensure_ascii=False) ``` ```python return f"""<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Amazon产品研究报告: {query}</title> <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script> ``` ```javascript const RAW_DATA = {data_json}; (function() { const grid = document.getElementById('productGrid'); const products = RAW_DATA.products || []; products.forEach(p => { const card = document.createElement('div'); card.className = 'product-card'; card.innerHTML = ` <img src="${p.image_url || 'https://via.placeholder.com/300x300/EEE/999'}" alt="${p.title}" onerror="this.src='https://via.placeholder.com/300x300/EEE/999?text=No+Image'"> <div class="title">${p.title}</div> <div class="stars">${'⭐'.repeat(Math.round(p.rating || 0))} ${p.rating}</div> <div class="price">${p.price || 'N/A'}</div> <div class="meta">${(p.total_reviews || 0).toLocaleString()} 条评论</div> <a href="${p.url}" target="_blank">查看详情 →</a> `; grid.appendChild(card); }); })(); ``` ```javascript document.getElementById('kwSummary').innerHTML = kd.summary || ''; document.getElementById('vocSummary').innerHTML = ...[truncated 2736 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never insert untrusted strings through `innerHTML`. Build elements with `document.createElement()` and assign textual values through `textContent`. 2. Store serialized data in a non-executable `<script type="application/json">` element and parse its `textContent`. 3. Before embedding JSON in HTML, escape at least `<`, `>`, `&`, U+2028, and U+2029. For example, replace `<` with `\u003c`. 4. Apply HTML attribute escaping to direct template substitutions such as the query and market. 5. Validate all URLs with `urllib.parse.urlparse()` and allow only expected HTTPS origins. Reject `javascript:`, `data:`, `file:`, and unexpected hosts. 6. Validate LLM responses against a strict schema with type, size, and character constraints. 7. Add a restrictive Content Security Policy that disallows inline scripts and limits network connections, images, and scripts to approved sources. 8. Add regression tests containing payloads in queries, titles, reviews, summaries, URLs, and all LLM-generated fields. ]]>

other

Warning
Location
scripts/ai_tagging.py:122
Finding
Indirect Prompt Injection Through Untrusted Product and Review Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ai_tagging.py:122-165`, `scripts/voc_clustering.py:91-135`, and `scripts/competitor_analysis.py:91-139` **Vulnerability Type**: Indirect prompt injection **Risk Level**: Medium ### Vulnerable Code ```python rating = review.get("rating", 0) title = review.get("title", "") body = review.get("body", "") max_body_length = 1500 if len(body) > max_body_length: body = body[:max_body_length] + "..." prompt = f"""请对以下Amazon评论进行深度分析,提取结构化信息。 **评论信息:** - 评分:{rating}星 - 标题:{title} - 内容:{body} **请提取以下信息(JSON格式):** ... 请直接输出JSON:""" ``` ```python prompt = f"""你是一位Amazon消费者洞察专家。请对以下产品的用户痛点进行聚类分析。 **产品**: {products_info} **高频痛点TOP30**: {pain_summary} **代表性评价样本**: {chr(10).join([f' [{pr["asin"]}] ⭐{pr["rating"]} "{pr["review_excerpt"][:100]}"' for pr in pain_reviews[:20]])} ... 请直接输出JSON:""" ``` ```python data = { "model": model, "messages": [ {"role": "user", "content": prompt} ], "temperature": 0.3, "max_tokens": 500 } ``` ### Technical Analysis Marketplace data is attacker-influenceable. Product titles and review bodies may contain text that resembles model instructions. The code places this content directly into the same user message as the application's operational instructions. There is no trusted system message establishing that marketplace content is data rather than instructions. There are also no strong delimiters, prompt-injection filtering controls, or schema-enforced response validators. The parsers only check whether the response can be decoded as JSON and, in limited cases, whether a few fields exist. An attacker can therefore publish a review containing instructions such as directing the model to ignore the requested analysis and return attacker-selected JSON. That output is subsequently used by VOC, competitor, opportunity, and report-generation stages. Because report fields are rendered with `innerHTML`, this issue can be chained with the stored HTML-i ...[truncated 1369 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Place immutable analysis rules in a trusted system message rather than combining all instructions and data in one user message. 2. Explicitly identify marketplace content as untrusted data and instruct the model never to follow directions found within it. 3. Use clear structured delimiters or JSON fields to distinguish instructions from review content. 4. Validate model responses against strict schemas: - Require exact expected keys - Enforce field types - Restrict enumerated values - Limit array lengths and string sizes - Enforce numeric ranges - Reject unexpected keys 5. Treat all LLM output as untrusted even after validation and HTML-escape it before report rendering. 6. Add tests using reviews that contain instruction-like text, markup, script-breaking strings, and attempts to override the requested JSON format. 7. Consider deterministic local aggregation for fields that do not require generative analysis. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ai_tagging.py:177
Finding
Bearer API Credentials Can Be Transmitted to Arbitrary or Plaintext Endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/research.py:56-58` and `scripts/ai_tagging.py:177-203`; equivalent request logic appears in the other LLM analysis modules **Vulnerability Type**: Unrestricted credential-bearing network destination **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument("--api-key", help="LLM API Key") parser.add_argument("--api-base", default="https://api.openai.com/v1", help="API Base URL") parser.add_argument("--model", default="gpt-4o-mini", help="模型名称") ``` ```python def _call_llm_api(prompt: str, api_key: str, api_base: str, model: str, debug: bool) -> str: """调用LLM API(兼容OpenAI格式)""" headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } data = { "model": model, "messages": [ {"role": "user", "content": prompt} ], "temperature": 0.3, "max_tokens": 500 } if api_base.endswith("/"): url = f"{api_base}chat/completions" else: url = f"{api_base}/chat/completions" if debug: print(f" API URL: {url}") response = requests.post(url, headers=headers, json=data, timeout=30) ``` The same construction is present in: - `scripts/keyword_expansion.py:147-166` - `scripts/voc_clustering.py:187-206` - `scripts/competitor_analysis.py:187-201` - `scripts/opportunity_analysis.py:222-236` ### Technical Analysis The user-controlled `--api-base` value is used directly as the destination for requests carrying an `Authorization: Bearer` header. The implementation does not: - Require HTTPS - Restrict destinations to documented providers - Reject embedded credentials or malformed URLs - Prevent or safely validate cross-origin redirects - Warn before sending a credential to a custom host Consequently, an invocation can direct the API key and prompt data to an arbitrary server. If an HTTP URL is used, the bearer token and review-de ...[truncated 1389 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require the `https` scheme for every credential-bearing request and reject plaintext HTTP. 2. Parse and validate the URL before use. Reject user-info components, malformed ports, fragments, and unsupported schemes. 3. Allowlist documented provider hosts by default. 4. For custom hosts, display the exact normalized destination and require explicit opt-in or confirmation before transmitting credentials. 5. Disable redirects for credential-bearing requests, or validate every redirect destination before forwarding an authorization header. 6. Use provider-specific keys so a key intended for one service is never automatically sent to another. 7. Avoid supplying secrets on the command line because they may appear in process listings and shell history. Prefer protected environment variables, standard input, or an operating-system credential store. 8. Redact authorization data and sensitive prompt content from all logs and error messages. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:4
Finding
Unpinned Dependencies and Unsafely Loaded Remote Report Script<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:4-11` and `scripts/generate_report.py:126` **Vulnerability Type**: Software supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```text # Core requests>=2.31.0 # HTML parsing (for scraping if needed) beautifulsoup4>=4.12.0 lxml>=4.9.0 # Data processing pandas>=2.0.0 ``` ```html <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script> ``` ### Technical Analysis The Python requirements use lower-bound-only constraints. A future installation may therefore select package releases that were never tested or audited with this Skill. No lock file or package hashes are present to ensure reproducible, integrity-checked installation. The reviewed scripts only require `requests` from this dependency list. `beautifulsoup4`, `lxml`, and `pandas` are not imported by the project, so they unnecessarily increase the dependency and transitive-dependency attack surface. Generated reports also load Chart.js from a CDN at viewing time. No Subresource Integrity hash is specified. As a result, report behavior depends on remote JavaScript that can change independently of the audited Skill package. Compromise of the CDN, its delivery path, or the referenced resource could result in script execution when a report is opened. This is not evidence that any listed dependency is currently malicious. It is an avoidable supply-chain weakness. ### Attack Path #### Python dependency path 1. A user installs the dependencies at a later date. 2. The package resolver selects arbitrary newer versions allowed by the `>=` constraints. 3. A compromised, malicious, or incompatible release is downloaded. 4. Package installation or subsequent import executes affected third-party code in the user's Python environment. #### Remote report-script path 1. The Skill generates a report containing the jsDelivr script reference. 2. The user opens the report while connected to the networ ...[truncated 756 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `beautifulsoup4`, `lxml`, and `pandas` unless concrete runtime functionality requires them. 2. Pin dependencies to reviewed versions and maintain a lock file. 3. Use package hashes with `pip --require-hashes` or an equivalent reproducible installation mechanism. 4. Regularly scan locked dependencies for known vulnerabilities and update them through a controlled review process. 5. Vendor the required Chart.js file into the Skill package so reports work offline and do not execute mutable remote code. 6. If CDN delivery must remain, specify an exact version, include a verified Subresource Integrity hash, set `crossorigin="anonymous"`, and apply a restrictive Content Security Policy. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (56)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises a comprehensive Amazon product research pipeline with multiple analytical stages and final report generation. The supplied code does not implement that end-to-end workflow; it is a narrow data-ingestion module for one ASIN's product details and reviews. While review collection is consistent with one part of the description, major claimed capabilities are absent in this code chunk, and the actual primary behavior is simply API-based review retrieval rather than full product research. Therefore the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a full-chain Amazon product research skill covering eight major stages from input query through interactive HTML reporting. The supplied code, however, is narrowly scoped to keyword expansion only. It accepts already-available product data and already-tagged reviews, builds summaries, calls an external chat completion API, and returns keyword-related JSON. This is a partial component of the declared system rather than an implementation of the stated end-to-end functionality. Additionally, the code performs outbound network access to an LLM API, which is a resource use not reflected in the empty declared permissions. Therefore the description does not accurately represent what this specific code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a comprehensive full-chain Amazon research system, but this code chunk only covers the initial product search step. It does not collect reviews, analyze sentiment, cluster VOC pain points, perform competitor or opportunity analysis, or generate any HTML report. The only network access shown is a product search request to a RapidAPI Amazon products endpoint, plus local mock-data generation as fallback. Therefore the implemented behavior in this supplied chunk is materially narrower than the declared purpose.

External Model or Provider Selection

High
Category
Excessive Agency
Content
**OpenAI**
```
--api-key sk-xxx --api-base https://api.openai.com/v1 --model gpt-4o-mini
```

**DeepSeek(国内推荐)**
Confidence
90% confidence
Finding
The skill allows arbitrary external model/provider selection via --api-base and --model, which expands the trust boundary and can route sensitive content to any compatible endpoint the operator specifies. Without manifest restrictions or allowlists, this increases the risk of accidental use of untrusted providers, data exfiltration, or SSRF-like misuse in environments that permit broad outbound access.

External Model or Provider Selection

High
Category
Excessive Agency
Content
**DeepSeek(国内推荐)**
```
--api-key sk-xxx --api-base https://api.deepseek.com/v1 --model deepseek-chat
```

**DashScope(阿里云)**
Confidence
90% confidence
Finding
The documented provider-selection mechanism includes third-party endpoints and models without any visible restriction policy. In a skill that processes product research and scraped reviews, unrestricted provider routing materially increases exposure because sensitive inputs may be sent to a provider with weaker security, different retention rules, or attacker-controlled infrastructure.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
请直接输出JSON:"""
    
    return prompt


def _call_llm_api(prompt: str, api_key: str, api_base: str, model: str, debug: bool) -> str:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises capabilities that require network access and file output, but it does not declare any tool scope such as permissions or allowed-tools. This weakens least-privilege controls and can allow the skill to obtain broader execution capabilities than users or the platform expect, especially because it writes HTML reports and sends data to external APIs.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The file presents the skill description, usage guidance, and FAQs almost entirely in Chinese, with no indication that the user can choose another language. This creates a language-policy concern because the skill appears to force a specific language without explicit user opt-in.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The manifest lists generic triggers such as "选品分析", "竞品分析", "产品研究", and "market research" without narrowing context or exclusions. These phrases are common in ordinary ecommerce or strategy conversations, so they could cause unintended invocation beyond this specific Amazon-focused skill.

External Transmission

Medium
Category
Data Exfiltration
Content
python ~/.workbuddy/skills/amazon-product-research/scripts/research.py \
  --query "portable bluetooth speaker waterproof" \
  --api-key YOUR_DEEPSEEK_KEY \
  --api-base https://api.deepseek.com/v1 \
  --model deepseek-chat

# OpenAI
Confidence
91% confidence
Finding
The skill instructs users to send queries and likely review content to an external LLM provider at DeepSeek. This creates a real data egress path: potentially sensitive business research inputs, scraped review datasets, and generated analysis can leave the local environment and be processed by a third party.

External Transmission

Medium
Category
Data Exfiltration
Content
| `--max-products` | ❌ | 5 | 最多分析的竞品数量 |
| `--max-reviews` | ❌ | 100 | 每个产品最大评论数 |
| `--api-key` | ❌ | - | LLM API Key(无Key则仅生成数据报告) |
| `--api-base` | ❌ | https://api.openai.com/v1 | API Base URL |
| `--model` | ❌ | gpt-4o-mini | 模型名称 |
| `--output` | ❌ | ./product_research_{timestamp}.html | 输出路径 |
| `--rapidapi-key` | ❌ | - | RapidAPI Key(可选) |
Confidence
90% confidence
Finding
The default API base points to OpenAI, meaning user-supplied research prompts and derived product/review data may be transmitted externally even in routine use. In a market-research context this can expose proprietary sourcing ideas, competitive intelligence, or other commercially sensitive inputs.

External Transmission

Medium
Category
Data Exfiltration
Content
**OpenAI**
```
--api-key sk-xxx --api-base https://api.openai.com/v1 --model gpt-4o-mini
```

**DeepSeek(国内推荐)**
Confidence
90% confidence
Finding
This section explicitly documents sending data to the OpenAI API, confirming third-party transmission. The risk is contextual rather than inherently malicious, but it is still security-relevant because the skill handles potentially sensitive market research content and lacks declared tool scoping in the manifest.

External Transmission

Medium
Category
Data Exfiltration
Content
**DeepSeek(国内推荐)**
```
--api-key sk-xxx --api-base https://api.deepseek.com/v1 --model deepseek-chat
```

**DashScope(阿里云)**
Confidence
90% confidence
Finding
This section documents transmission to DeepSeek, another third-party endpoint. Sending user queries, review text, and analytic prompts to an external provider can create confidentiality and compliance risks if users assume the skill runs locally or do not understand cross-border data handling.

External Transmission

Medium
Category
Data Exfiltration
Content
--max-products 5 \
  --max-reviews 100 \
  --api-key YOUR_KEY \
  --api-base https://api.deepseek.com/v1 \
  --model deepseek-chat
```
Confidence
88% confidence
Finding
The example command again directs users to transmit data to an external DeepSeek endpoint, reinforcing that network egress is part of normal operation. Repetition in examples can normalize data sharing without enough emphasis on the sensitivity of competitive research data.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The prompt instructs that if a review is in English, it must be translated into Chinese before analysis. This imposes a specific language behavior without user opt-in or any documented locale choice, which matches the language/locale policy violation criteria.

External Transmission

Medium
Category
Data Exfiltration
Content
if debug:
        print(f"    API URL: {url}")
    
    response = requests.post(url, headers=headers, json=data, timeout=30)
    
    if response.status_code == 200:
        result = response.json()
Confidence
95% confidence
Finding
This code performs outbound transmission of constructed prompts containing review title, body, and rating to a remote API endpoint. External transmission is security-relevant here because the skill handles collected review content at scale, and the destination can be user-configurable through api_base, increasing the risk of accidental data leakage to untrusted endpoints.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The module sends raw review text to an external LLM API via requests.post, but there is no visible consent, warning, or data-handling control in this file before transmitting potentially sensitive review content. In a product-research skill that may process third-party marketplace data, silent external transmission creates privacy, compliance, and user-trust risk, especially if reviews or metadata contain personal information.

Ssd 4

Medium
Confidence
86% confidence
Finding
User-controlled review-derived content is concatenated directly into the LLM prompt as plain text, without clear delimiting, structured serialization, or higher-priority system safeguards. Malicious review text or product metadata could steer the model's analysis, degrade output integrity, or induce malformed JSON responses, which is especially relevant in a workflow that automates market research conclusions.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The prompt explicitly requires the model to produce the overall summary in Chinese and only outputs Chinese instructions, which imposes a locale/language constraint. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the restriction is clearly justified or optional.

External Transmission

Medium
Category
Data Exfiltration
Content
url = api_base.rstrip("/") + "/chat/completions"
    if debug:
        print(f"  API: {url} | Model: {model}")
    response = requests.post(url, headers=headers, json=data, timeout=60)
    if response.status_code == 200:
        return response.json()["choices"][0]["message"]["content"]
    raise Exception(f"API调用失败: HTTP {response.status_code}")
Confidence
88% confidence
Finding
The code performs an outbound HTTP request to a configurable API endpoint carrying the assembled prompt and authorization header. Because the prompt includes product and review-derived data and api_base is caller-controlled, this can transmit sensitive business content to third parties or a malicious endpoint, extending the exposure beyond normal local processing.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The module sends product and review-derived analysis data to an external LLM API via requests.post, but there is no code-level notice, consent flow, redaction, or configurable privacy control before transmission. In a product-research skill, review text and competitor intelligence may contain sensitive business data or user-provided content, so undisclosed third-party transfer creates a real data exposure and compliance risk.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code uses Chinese in the module docstring and throughout user-visible status/output messages, with no option to select another language or any justification that the skill is intended only for Chinese-speaking users. That creates a natural-language locale policy issue because the skill imposes a specific language by default.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The manifest describes end-to-end Amazon product research across markets, and the function signature/documentation accepts a market parameter with multiple supported country codes. However, both product-detail and review requests hardcode `country: "US"`, so non-US analysis requests will not actually fetch marketplace-specific data as implied.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The module docstrings and generated HTML content are written in Chinese, and the HTML declares `lang="zh-CN"`, indicating a fixed Chinese locale for user-facing output. There is no indication that users can opt into another language or that the locale restriction is intentionally limited to a China-specific use case.

Static analysis

No suspicious patterns detected.