Back to skill

Security audit

Keepa-商品历史数据

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly supports Amazon history lookups, but it also includes under-scoped account, billing, credential, local persistence, and automatic feedback-reporting behavior that users should review carefully.

Install only if you are comfortable with LinkFox account onboarding, paid quota flows, local saving of full API responses, and external feedback reporting. Avoid setting custom LINKFOX_* endpoint variables, treat printed API keys and SMS codes as secrets, and review payment actions before approving them.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (5)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:174
Finding

Automatic Disclosure of User Feedback and Intent to an External Service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:72
Finding

Environment-Controlled Endpoints Can Receive Authentication Credentials

Content
View full analysis
str: return _env_base("LINKFOX_AGENT_API_URL", "https://tool-gateway.linkfox.com", "LINKFOX_TOOL_GATEWAY") def _login_base() -> str: return _env_base("LINKFOX_LOGIN_API_URL", "https://api.linkfox.com") def _agent_user_base() -> str: return _env_base("LINKFOX_AGENT_USER_API_URL", "https://agent-api.linkfox.com") ``` ```python def _headers(source: str, origin_host: str, *, access_token: str = "", user_id: str = "", group_id: str = "") -> dict: h = { "Accept": "application/json, text/plain, */*", "Content-Type": "application/json;charset=UTF-8", "Origin": f"https://{origin_host}", "Referer": f"https://{origin_host}/", "source": source, "User-Agent": UA, } if access_token: h["authorization"] = access_token h["uid"] = _uid_header(access_token, user_id) if user_id else _LOGIN_FIXED_UID if group_id: h["tid"] = group_id return h ``` ```python def _login_by_token(access_token: str, refresh_token: str) -> dict: resp = _http_post(f"{_agent_user_base()}/account/loginByToken", { "token": access_token, "refreshToken": refresh_token, "device": {"aid": "3026344186", "did": "", "type": "Windows", "os": "10", "model": "149.0.0.0", "brand": "Chrome"}, }, _headers("agent-linkfox-web", "agent.linkfox.com", access_token=access_token)) ``` ```python def _fetch_user_info_v3(access_token: str, user_id: str) -> dict: resp = _http_post(f"{_login_base()}/linkFoxApp/api/userCenter/userInfo", {}, _headers("agent-linkfox-web", "agent.linkfox.com", access_t ...[truncated 2603 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:487
Finding

Generated API Key Is Disclosed Through Standard Output

Content
View full analysis
None: print(json.dumps(obj, ensure_ascii=False, indent=2)) ``` ```python 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 ``` ### Technical Analysis After SMS authentication, the complete generated API key is returned in a dictionary and serialized to standard output. Standard output is commonly captured by Agent transcripts, orchestration systems, CI logs, terminal recording, shell redirection, or monitoring infrastructure. Masking the phone number does not protect the API key. The key is the most security-sensitive value in the returned object and is exposed without any output-channel protection. ### Attack Path 1. The user runs `onboarding.py login` with a phone number and verification code. 2. The script obtains or generates an API key. 3. `login_and_get_key` places the complete key in the result object. 4. `_cmd_login` passes that object to `_emit`. 5. `_emit` prints the complete JSON object to standard output. 6. A transcript, log collector, shared terminal, or CI artifact retains the key. 7. A party with access to that retained output reuses the key. ### Impact Assessment An exposed key can authorize any operation permitted by that LinkFox API credential, including potentially chargeable product-history queries and account or billing-related g ...[truncated 186 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:147
Finding

Unsanitized Session Identifier Permits Output-Path Traversal

Content
View full analysis
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 ``` The product-history script contains the equivalent behavior: ```python def _session_id(ts: float) -> str: env = os.environ.get("SESSION_ID") if env: return env.strip() if "_auto" not in _SESSION_CACHE: _SESSION_CACHE["_auto"] = ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3) ) return _SESSION_CACHE["_auto"] def _ensure_session(ts: float) -> tuple[str, str]: date_str = time.strftime("%Y-%m-%d", time.localtime(ts)) sid = _session_id(ts) root = _linkfox_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _ensure_meta(root, session_dir, date_str, sid, ts) return root, session_dir ``` ### Technical Analysis `SESSION_ID` is incorporated into a filesystem path without character restrictions or post-resolution containment validation. Python's `os.path.join` discards preceding components when a later component is absolute. Relative values containing `..` can also escape the intended directory. The resulting directory is used for response data, metadata, and QR image output. The script can therefore create directories and write files outside the expected LinkFox session tree with the privileges of the executing process. ### Attack Path 1. An attacker controls or influences the `SESSION_ID` environment variable. 2. The ...[truncated 956 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
Finding

Installation Guidance Uses Unpinned Runtime Dependencies

Content
View full analysis
dict: try: import qrcode except ImportError: err = "缺少 qrcode 依赖,请运行: pip install qrcode pillow" print(f"{TAG} render_qr: {err}", file=sys.stderr) return {"png_path": None, "ascii_qr": None, "error": err} ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError("缺少 requests 依赖,请运行: pip install requests") ``` ### Technical Analysis When dependencies are missing, the script instructs the user to install `qrcode`, `pillow`, and `requests` without version constraints, hashes, a lockfile, or a specified trusted package index. Unpinned installation is not proof that the named packages are malicious. However, it makes the installation mutable over time and exposes users to compromised future releases, malicious package-index substitution, dependency confusion in a misconfigured environment, or incompatible versions. ### Attack Path 1. One of the optional dependencies is absent. 2. The script displays an installation command. 3. The user executes the command in an environment whose package index or resolver can be influenced. 4. `pip` resolves the latest available versions and transitive dependencies without integrity pinning. 5. A compromised or substituted package executes code during installation or when imported by the onboarding script. ### Impact Assessment Python package installation and import execute code with the privileges of the invoking user. A compromised dependency could access files, environment variables, LinkFox credentials, Agent transcripts, and network resources available to that user. The practical likelihood depends on package-index integrity and environment configuration, so this issue is rated Low rather tha ...[truncated 62 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (26)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request sent via urlopen includes multiple headers sourced directly from environment variables, and the destination host is also overridable via LINKFOX_TOOL_GATEWAY. This creates a real exfiltration path: in a hostile or multi-tenant runtime, secrets and contextual identifiers such as the API key, SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME can be transmitted to an attacker-controlled endpoint without validation.

Content

Scanner excerpt · scripts/keepa_product_history.py (reported line 80)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) 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
93% confidence
Finding

The POST destination is derived from environment-controlled base URLs, and the function sends sensitive authentication material such as access tokens, refresh tokens, phone numbers, SMS codes, and generated API keys to those endpoints. In a skill execution environment, an attacker who can influence environment variables can redirect these requests to attacker-owned infrastructure, causing credential exfiltration and account compromise.

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
93% confidence
Finding

The gateway URL is built from environment-controlled configuration and then used by urllib with the Authorization header populated from the agent API key. If that base URL is redirected, the skill will transmit the API key and potentially billing/order data to an attacker-controlled server, enabling unauthorized API use and account abuse.

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

This is a significant description-behavior mismatch: the skill claims to retrieve Amazon historical product data, but the detected behavior includes account login, API key generation, user/team info access, plan browsing, order creation, payment-status polling, and QR-code/payment artifact generation. Hidden authentication and payment flows can expose personal data, trigger unintended purchases, or coerce users into off-purpose account actions without informed consent.

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 124)May include surrounding context.

asin: B0XXXXXXXX, domain: 1, days: 90, showPrice: 1, showPriceList: 1, showPriceDeal: 1, showPricePrime: 1, showPriceFba: 1, showPriceFbm: 1, showPriceCoupon: 1, showBsrMain: 1, showSellerCount: 1

text

## Display Rules

1. **Present data clearly**: Show time-series data in tables or describe trends; avoid subjective business advice unless the user explicitly asks for it.
2. **BSR clarification**: When showing BSR data, remind users that lower values mean better (higher) sales ranks.

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

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation claims writing to /tmp is forbidden and that the script should fail if the current directory is not writable, but the implementation silently falls back to home and temp directories. This mismatch is dangerous because operators may rely on the documented storage restrictions and unknowingly allow sensitive responses to be written to broader or less-monitored locations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements account onboarding, SMS authentication, API key issuance, subscription/package management, and payment handling, which is materially different from the declared skill purpose of retrieving Amazon product historical analytics. Such capability drift is dangerous because users and reviewers may grant trust based on the manifest while the code performs identity and billing operations with access to credentials and payment artifacts.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code can create orders, fetch payable URLs, and render payment QR codes even though the skill is advertised as a product-history data tool. Embedding billing flows in a mismatched skill increases the risk of deceptive purchases, unauthorized charges, or social engineering because the capability is not justified by user expectations or the manifest.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script performs SMS-based login, token exchange, team selection, and API key retrieval/generation, none of which are necessary for answering Amazon product-history questions. In the stated skill context, this makes the code more dangerous because it solicits and processes credentials under a benign analytics pretense, increasing the likelihood of over-collection and secret exposure.

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 use environment variables, write files, and access networked APIs, yet it declares no explicit tool scope or permission boundary. That creates unnecessary privilege ambiguity: a caller or runtime may grant broader access than users expect, increasing the blast radius if the skill is abused or mis-triggered.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation criteria are broad enough to match generic product-research or pricing questions, which can cause the skill to trigger in contexts where the user did not intend a Keepa/LinkFox query. In this skill, that is more dangerous because each invocation may consume paid quota and may lead users into hidden onboarding or billing-related behavior described elsewhere in the file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instruction requires the agent to explain additional compute cost to the user using Chinese text in a mixed-language skill, but the file does not offer the user a language preference or document a justified locale restriction. This can violate language/locale policy because the skill imposes a specific language behavior rather than adapting to the user's chosen language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The line requires a user warning before proceeding with potentially high compute-cost operations, but the instruction is written as an unconditional Chinese-language requirement rather than a user-language-aware disclosure. Because no opt-in or locale justification is provided, this is a natural-language policy issue under the language/locale rule.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/api.md (reported line 70)May include surrounding context.

}

text

## curl 示例

```bash
curl -X POST https://tool-gateway.linkfox.com/keepa/productSeries \

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation adds a separate feedback submission API that is unrelated to the core product-history retrieval function. This creates scope creep and increases the chance that an agent will transmit user-derived content to an external endpoint without a clear user request, especially because the example encourages sending free-form content about user satisfaction or problems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The feedback API section instructs posting a content field that may include what the user said or intended, but it provides no warning that this information will be sent to an external service. Without a disclosure and consent requirement, an agent could exfiltrate user prompts, preferences, or complaint details to a third party in a way the user does not expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The onboarding flow explicitly instructs collecting a user's phone number and verification code to register/login through a script, but it does not provide any privacy notice, consent language, data handling limits, or guidance on protecting the submitted personal data. In a skill context, this creates a real privacy and sensitive-data handling risk because users may be induced to share personal identifiers and OTP material through the agent workflow without understanding how that data will be transmitted, stored, or used.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script always writes the full API response to disk without an explicit user-facing confirmation at runtime, despite handling potentially sensitive commercial and session-linked data. In the context of a query skill, silent persistence broadens exposure to local users, other processes, backups, and forensic recovery, especially because the user may reasonably expect a transient lookup rather than retention.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The inline comment for SMALL_THRESHOLD says small responses are '直接全量输出,不落文件'. In main(), the script serializes the result, resolves an output path, and writes the full response unconditionally before deciding whether to print inline or summarize.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script persistently stores full API responses, cache entries, and session metadata even though the skill is described as a query tool. This increases data-retention risk by leaving potentially sensitive product intelligence, usage metadata, and session linkage on disk beyond the immediate request lifecycle.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

_resolve_output_path() documents a fixed <cwd>/linkfox/... destination. In reality it delegates to resolve_data_path() via _ensure_session() and _linkfox_root(), which may choose multiple alternate roots and therefore does not guarantee a current-working-directory path.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's CLI description and user-facing messages are entirely in Chinese, and the workflow is constrained to '+86' domestic phone numbers and China-specific payment methods. The policy allows locale constraints only when clearly documented and justified or when users are given a choice; this file does not offer language or locale choice, and the region restriction is not explicitly justified as a region-specific tool.

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 = ""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code generates or retrieves an API token and returns it in command output without any embedded warning, masking, or constrained handling guidance. Returning sensitive tokens directly increases the chance of accidental disclosure through logs, transcripts, terminal history, downstream tooling, or prompt-injection-assisted exfiltration.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.