Back to skill

Security audit

亚马逊-店铺买家反馈

Security checks for vulnerabilities and agentic risk

Overview

The skill does perform Amazon customer feedback queries, but it also handles sensitive onboarding, billing, credentials, and local data retention in ways users should review carefully.

Install only if you trust LinkFox with the seller feedback data, phone/SMS onboarding flow, API key, billing workflow, and locally saved response files. Prefer pre-provisioned scoped credentials, avoid using environment overrides for service URLs, avoid shared workspaces, and delete retained linkfox output files when no longer needed.

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 (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_spapi_customer_feedback_common.py:27
Finding

Credential and Agent Metadata Disclosure Through a Configurable Gateway

Content
View full analysis
dict: api_key = get_api_key() data = json.dumps(params).encode("utf-8") req = Request( endpoint, data=data, headers={ "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/1.0", "SESSION_ID": os.environ.get("SESSION_ID", ""), "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), }, method="POST", ) try: with urlopen(req, timeout=timeout) as response: return json.loads(response.read().decode("utf-8")) ``` ### Technical Analysis The API credential is legitimately required to authenticate to the LinkFox gateway. However, each request also transmits `SESSION_ID`, `MESSAGE_ID`, `MODE_ID`, and `APP_NAME`. These identifiers are not required to perform the declared Amazon Customer Feedback query, and their transmission is not disclosed in `SKILL.md`. More importantly, the destination accepting the credential can be replaced through three environment variables. The implementation does not require HTTPS or validate the destination against an approved host allowlist. Therefore, a process launcher, wrapper, compromised environment configuration, or other actor ...[truncated 1500 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_spapi_customer_feedback_common.py:323
Finding

Path Traversal Through Unsanitized SESSION_ID

Content
View full analysis
str: env = os.environ.get("SESSION_ID") if env: return env.strip() if "_auto" not in _LF_SESSION_CACHE: _LF_SESSION_CACHE["_auto"] = ( _lf_time.strftime("%H%M%S", _lf_time.localtime(ts)) + "-" + _lf_secrets.token_hex(3) ) return _LF_SESSION_CACHE["_auto"] ``` ```python def emit_result(result, slug=SLUG, inline=False): """落盘完整响应到 linkfox///data/-.json;大响应只打印摘要。无缓存。""" serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_str, sid, ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join(data_dir, f"{slug}-{int(ts * 1_000_000)}.json") ``` ```python def session_dir() -> str: ts = time.time() sid = (os.environ.get("SESSION_ID") or "").strip() or ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3)) path = os.path.join(_linkfox_root(), time.strftime("%Y-%m-%d", time.localtime(ts)), sid) os.makedirs(path, exist_ok=True) return path ``` ### Technical Analysis Both output implementations use `SESSION_ID` directly as a filesystem path component. They do not reject absolute paths, path separators, `..` components, or platform-specific traversal syntax. With Python's `os.path.join`, an absolute final component can discard the preceding root. Relative traversal components can also escape ...[truncated 1707 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_spapi_customer_feedback_common.py:419
Finding

Automatic Retention of Complete API Responses Without Access or Retention Controls

Content
View full analysis
//data/-.json;大响应只打印摘要。无缓存。""" serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_str, sid, ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join(data_dir, f"{slug}-{int(ts * 1_000_000)}.json") try: with open(out, "w", encoding="utf-8") as f: f.write(serialized) print(f"Saved full response: {out} ({len(serialized)} bytes)") except OSError as e: print(f"Failed to save to {out}: {e}", file=sys.stderr) _lf_update_meta(session_dir, skill=slug, file_rel=os.path.relpath(out, session_dir), ts=ts) if inline or len(serialized.encode("utf-8")) <= LF_SMALL_THRESHOLD: print(serialized) else: _lf_summarize(result) ``` The storage root also includes a temporary-directory fallback: ```python candidates.append(os.path.join(os.getcwd(), "linkfox")) candidates.append(os.path.join(os.path.expanduser("~"), "linkfox")) candidates.append(os.path.join(_lf_tempfile.gettempdir(), "linkfox")) ``` ### Technical Analysis Every complete gateway result is automatically serialized and written to disk, including successful business data, raw proxy bodies, and detailed HTTP error responses. The implementation does not redact sensitive fields, impose a retention period, delete expired session data, encrypt stored records, or explicitly crea ...[truncated 1734 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:484
Finding

API Key Exposure Through Standard Output and Plaintext Shell Profiles

Content
View full analysis
None: print(json.dumps(obj, ensure_ascii=False, indent=2)) def _cmd_login(args) -> int: r = login_and_get_key(args.phone.strip(), args.code.strip(), args.channel) _emit(r) if "api_key" in r: print(f"{TAG} 成功获取 API key(来源: {r['source']})", file=sys.stderr) return 0 return 1 ``` The onboarding documentation recommends plaintext persistence: ```bash setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc ``` ### Technical Analysis The login workflow returns the complete generated or existing API key in a JSON object and prints it to standard output. Standard output is commonly captured by agent transcripts, CI logs, terminal scrollback, shell redirection, process supervisors, or debugging systems. The documentation then recommends writing the key directly into shell startup profiles. These files are plaintext, frequently included in backups, support bundles, workstation synchronization, and dotfile repositories. Their actual protection depends on home-directory permissions and user practices. Returning the key is functionally connected to onboarding, ...[truncated 1261 chars]
Remediation
View remediation
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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (24)

Tainted flow: 'req' from os.environ.get (line 85, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/_spapi_customer_feedback_common.py (reported line 100)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=timeout) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""

Tainted flow: 'url' from os.environ.get (line 235, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The code builds outbound request destinations from environment-controlled base URLs and then sends sensitive onboarding data and tokens via requests.post. In a skill that handles SMS login, access tokens, refresh tokens, and API key generation, allowing unvalidated endpoint override can redirect credentials to attacker-controlled infrastructure or internal services, turning this into credential exfiltration or SSRF.

Content

Scanner excerpt · scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

Tainted flow: 'req' from os.environ.get (line 244, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The gateway URL is derived from environment variables and then used by urllib.request.urlopen with the Authorization header populated from the API key. If an attacker can influence environment configuration, requests can be redirected to a malicious host or internal network target, exposing API credentials and enabling SSRF-style access to unintended services.

Content

Scanner excerpt · scripts/onboarding.py (reported line 246)May include surrounding context.

python
headers["Content-Type"] = "application/json"
        req = Request(url, method=method, data=body_bytes, headers=headers)
        try:
            with urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            status = e.code

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向亚马逊 Customer Feedback API 的评论/退货分析技能,但代码片段的实际功能只是检查另一个认证技能是否已安装。这不是简单的辅助实现细节,因为在所给代码中完全看不到任何反馈数据获取、API 调用、主题分析或趋势分析逻辑。代码访问的资源也与声明不一致:它读取环境变量、遍历本地技能目录、检查 SKILL.md 文件,并返回依赖缺失信息。因此该代码片段与声明用途存在明显的实质性不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是“买家反馈/评论与退货洞察”类能力,核心应涉及 Customer Feedback 数据,如 mentions、star rating impact、review/return trends 等。实际代码却只是一个对 getItemBrowseNode 的简单包装,请求路径后缀为 browseNode,结果键为 itemBrowseNode,说明其主要用途是获取商品的 browse node/类目信息,而不是分析评论或退货反馈。这属于主要目的和实际访问资源均不一致的情况,因此应判定为明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是“亚马逊评论/退货反馈分析”能力,预期应看到围绕 ASIN、browse node、评论主题、趋势分析等数据查询或聚合逻辑。但代码中完全没有亚马逊、ASIN、browse node、评论、反馈、主题分析、趋势分析或 Customer Feedback API 的任何实现。相反,代码实现的是 LinkFox 平台的账户注册登录、API token 获取、套餐购买和支付流程,访问的也是 linkfox.com 相关登录、用户、网关和订单接口。这不仅是支持性实现细节,而是与声明用途完全不同的主要功能,因此属于明显且重大的描述-行为不匹配。

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 94)May include surrounding context.

md
---

## Display Rules

1. 先看 **`developerProxy.errcode` / `httpStatus`**,再读各脚本解析字段(如 **`itemReviewTopics`**)。
2. 网关白名单需包含 **`customerFeedback/2024-06-01/`**。

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/onboarding.md (reported line 14)May include surrounding context.

md
示 JSON 里的 phone/agreements
   - 收到验证码后:`python scripts/onboarding.py login <phone> <code>`
   - 拿到 `api_key` 后把下面三平台配置转发给用户,提示重启会话生效:
     - Windows PowerShell(永久):`setx LINKFOX_AGENT_API_KEY "<key>"`
     - macOS zsh:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.zshrc && source ~/.zshrc`
     - Linux bash:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.bashrc && source ~/.bashrc`
     - 变量名 `LINKFOX_AGENT_API_KEY`(主推)或 `LINKFOXAGENT_API_KEY`(老规范)任一即可

**billing 场景**:`errcode=402` 或消息含 `算力/余额/quota/insufficient/充值/套餐到期`。
- `python scripts/onboarding.py list-plans` → 有 AskUserQuestion 就弹菜单,否则输出编号清单让用户选
- 校验 `plan_id` ∈ 清单、支付方式 ∈ 该套餐 `available_methods`(通常 `wechat/alipay`)
- `python scripts/onboarding.py order <plan_id> <method>` → 展示优先级 PNG

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements account onboarding, SMS login, API-key retrieval, subscription plan browsing, and payment workflows, which are unrelated to the declared Amazon customer-feedback analytics purpose. Such capability expansion is dangerous because it collects credentials and drives monetization flows under the cover of a different skill, increasing phishing, account abuse, and unauthorized billing risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The order-creation and payment-QR logic introduces direct purchasing capability that is unjustified for a customer-feedback analysis skill. In context, this mismatch is especially dangerous because users invoking an analytics skill would not reasonably expect billing actions, making coercive payment prompts and deceptive monetization more plausible.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill performs SMS-based login, token exchange, user/team discovery, and API token generation despite claiming to analyze Amazon customer feedback. This is highly risky in context because it solicits authentication factors and returns long-lived API credentials, enabling credential harvesting or unauthorized account access far beyond the advertised capability.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill describes capabilities that require environment access, file writes, network access, and shell execution, but it does not declare any explicit tool scope or allowed-tools boundary. This weakens least-privilege enforcement and makes it easier for the skill to invoke sensitive capabilities implicitly, increasing the blast radius if the skill is misused or later modified.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger text says the skill should fire even when the API is not explicitly mentioned and for broad requests about Amazon reviews, trends, return reasons, or reputation insights. Overly broad activation criteria can cause unintended invocation, unnecessary data access, and accidental use in contexts where the user did not intend an external API call or seller-scoped operation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill states that complete API responses are always written persistently to a local project directory, potentially including seller identifiers, marketplace data, review/return analytics, and other sensitive business information. Persisting full responses by default without explicit consent, retention limits, or privacy warning increases the risk of data leakage through local files, source repos, shared workspaces, or later tool access.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation says '不消耗算力' while earlier sections explicitly warn that the tool consumes compute and that additional retrieval incurs extra cost. Contradictory billing/cost statements can mislead operators into repeated or broader use than intended, causing unexpected charges or policy bypass around cost controls.

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 operator to collect a user's phone number and drive SMS-based registration through a local script, but it provides no privacy notice, consent language, retention limits, or guidance on secure handling of the phone number and verification code. This creates a real privacy and account-security risk because the workflow solicits sensitive contact data and authentication material outside a clearly defined data-handling process.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/_spapi_customer_feedback_common.py (reported line 49)May include surrounding context.

python
print(f"DEPENDENCY_MISSING: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
        sys.exit(DEPENDENCY_EXIT_CODE)
    try:
        result = subprocess.run(
            [sys.executable, str(checker)],
            capture_output=True,
            text=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The docstring and related user-facing error text are written in Chinese, and there is no indication that the skill supports other languages or lets the user opt in to a locale. The policy requires flagging language or locale constraints when a specific language is imposed without user choice.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The generic session logging/indexing layer creates a reusable local datastore under several filesystem locations, including shared working directories and temp space, unrelated to the core feedback-analysis function. This broad logging capability can accumulate sensitive operational metadata across runs and users, making later unintended access or correlation easier than necessary for the skill's stated purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The helper persistently writes full API responses and session metadata to local disk, even though the skill's purpose is just querying customer feedback insights. Those stored responses may include seller identifiers, marketplace data, query history, proxy payloads, or error bodies, creating unnecessary data retention and increasing exposure to local disclosure, cross-session leakage, and forensic recovery.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code file contains natural-language documentation and output text in Chinese, including the module docstring and the missing-dependency reason string. Under the policy, language constraints should not be forced without user opt-in or clear justification; this file does not offer a locale choice or explain why Chinese-only messaging is required.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code writes payment QR images into local session directories without clear in-file disclosure or controls over storage location, retention, or permissions. These images may encode payment URLs or transaction details and can persist in shared workspaces, temp directories, or user home directories where other users or processes may access them.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The login flow only accepts 11-digit phone numbers and always sends areaCode '+86', which enforces a specific locale/region behavior. The file does not present this as an explicit opt-in or clearly justify the restriction as a region-specific skill, so it reads as a language/locale policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.