Back to skill

Security audit

Keepa-商品搜索

Security checks for vulnerabilities and agentic risk

Overview

The skill can perform the advertised Keepa product search, but it also adds silent feedback reporting plus account, billing, credential, and local-storage behaviors that need review before installation.

Review this skill before installing. Use it only if you intend to use LinkFox's paid Keepa gateway, are comfortable with API-key and phone/SMS onboarding flows, and will explicitly approve any plan purchase or payment order. Avoid running it with untrusted environment variables, do not paste OTPs or API keys into shared logs, and prefer a safer secret store over shell profile files.

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

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:267
Finding

Silent transmission of conversation-derived feedback to a separate service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:484
Finding

API key disclosed through stdout and recommended for plaintext persistent storage

Content
View full analysis
int: r = login_and_get_key(args.phone.strip(), args.code.strip(), args.channel) _emit(r) if "api_key" in r: print(f"{TAG} Successful API key retrieval", file=sys.stderr) return 0 return 1 ``` The onboarding documentation recommends permanent plaintext storage: ```text setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc ``` ### Technical Analysis The complete API key is emitted as JSON to stdout. In an Agent environment, stdout can be copied into conversation context, execution logs, terminal transcripts, CI logs, observability systems, or debugging records. The documentation then instructs the Agent to forward the key to the user and place it directly in shell startup files. These files are long-lived plaintext configuration files and may be readable by local applications, backup tools, support bundles, or other users when file permissions are weak. Commands containing the key may also remain in shell history. The key is used as an authorization credential for billable gateway and account operations. Therefore, exposing it is materially more dangerous than displaying a non-secret configuration value. ### Attac ...[truncated 997 chars]
Remediation
View remediation

other

Warning
Location
scripts/keepa_product_search.py:60
Finding

Unnecessary session and Agent metadata transmitted with every product search

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/keepa_product_search.py:250
Finding

Unsanitized SESSION_ID permits output path traversal

Content
View full analysis
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) ``` The onboarding script uses the same unsafe value: ```python 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) ``` ### Technical Analysis `SESSION_ID` is accepted without validation and used directly as a filesystem path component. Values containing path separators, parent-directory segments, or an absolute path can cause `os.path.join` and path normalization to resolve outside the intended date and session directories. Subsequent code writes response JSON, metadata, index entries, or QR images into directories derived from this value. The implementation does not resolve the final path and verify that it remains under the selected LinkFox root. Exploitation requires influence over the process environment. This is plausible in Agent runners, wrappers, CI jobs, or shared execution environments where session metadata is externally supplied. ### Attack Path 1. An attacker or compromised launc ...[truncated 884 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/keepa_product_search.py:93
Finding

Complete API responses cached and persisted with unsafe fallback and default permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/keepa_product_search.py:36
Finding

Environment-controlled API endpoints can receive production credentials without validation

Content
View full analysis
str: return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") def get_api_url(): sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "_shared")) return get_api_base() + API_PATH ``` The API key is sent to the resulting URL: ```python headers = { "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/2.0", } req = Request(api_url, data=data, headers=headers, method="POST") ``` Onboarding accepts further environment-controlled service bases: ```python def _agent_base() -> 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") ``` ### Technical Analysis The scripts do not enforce HTTPS, validate hostnames, or distinguish development credentials from production credentials when endpoint overrides are used. A malicious or compromised launcher can modify the environment and redirect authenticated traffic. Depending on the overridden base, the resulting requests may include an API key, phone number, SMS verification code, access token, refresh token, user identifier, team identifier, or member identifier. Plain HTTP endpoints would additionally expose t ...[truncated 1214 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
Finding

Runtime instructions recommend installation of unpinned dependencies

Content
View full analysis
Remediation
View remediation
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (23)

Tainted flow: 'req' from os.environ.get (line 73, 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/keepa_product_search.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
94% confidence
Finding

The code allows network destinations to be overridden via environment variables and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API tokens to those endpoints. In a skill execution environment where env vars may be influenced by deployment or another component, this becomes an exfiltration/SSRF primitive against highly sensitive credentials.

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

The gateway URL is derived from environment variables and used to construct outbound urllib requests that carry the API key in the Authorization header. If an attacker can control the environment or deployment configuration, they can redirect requests to an attacker-controlled server and capture the API key or abuse the process as an SSRF client.

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

The skill is presented as a product search utility, but the behavior described by the analyzer includes authentication, account lookup, subscription/package listing, payment order creation, QR code generation, and payment-status checks. Hidden or under-declared account and payment flows are dangerous because they can collect personal data, trigger billing-related actions, or expand the blast radius far beyond the user's apparent request.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger conditions are extremely broad and explicitly say the skill should activate even when the user does not mention Keepa, as long as the request resembles advanced product research. Overbroad triggering can cause the agent to route generic commerce requests into a higher-cost, networked workflow without clear user intent or 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 214)May include surrounding context.

{"domain": "1", "brand": ["Anker", "UGREEN"], "isHazMat": false, "sort": [{"fieldName": "monthlySold", "sortDirection": "desc"}]}

text

## Display Rules

1. **Present data clearly**: Show search results in well-structured tables with key fields: ASIN, title, price, BSR, monthly sales, rating, review count, brand
2. **Price conversion**: Convert prices from smallest currency unit to standard format (e.g., 2599 -> $25.99)

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

This file implements account onboarding, token acquisition, subscription/package handling, order creation, and payment QR generation, which are unrelated to the stated Keepa/Amazon product-search purpose. That mismatch is dangerous because it expands the skill from search functionality into credential collection and monetization flows, increasing the chance of deceptive data harvesting and unauthorized billing behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code contains package purchasing, order creation, and payment QR generation even though the skill is presented as a product-search utility. In this context, hidden commerce functions are especially risky because they can steer users into purchasing subscriptions or expose billing data without a legitimate need tied to the declared skill behavior.

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 login, obtains access/refresh tokens, queries team information, and generates or retrieves API keys, none of which are necessary for Keepa-based product search. In a mismatched skill, these flows amount to credential collection and privileged token issuance under a misleading feature description.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares capabilities that involve environment access, file writes, and network activity, but it does not define an explicit tool scope or permission boundary. That increases the chance the agent will perform higher-risk actions than the user expects, especially because the document includes instructions to read environment variables, call APIs, and write session-linked files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Defaulting silently to the US marketplace can cause queries to be executed against the wrong region, sending user search terms and filters to an unintended external service context. This is mainly an integrity and privacy issue rather than a direct compromise, but it can still produce misleading results and unnecessary paid API usage.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to always persist full API responses to a session-linked local path under the current working directory. Persisting complete responses by default can retain sensitive search inputs, account-related metadata, or commercially sensitive results beyond the immediate interaction, increasing exposure to other processes, users, or later unintended access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file is written entirely in Chinese and provides no indication that users may choose another language or that the locale restriction is required for a region-specific purpose. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

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

}

text

## curl 示例

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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The onboarding flow instructs the agent to collect a user's phone number and OTP-based login data to obtain an API key, but it provides no privacy, consent, retention, or minimization guidance for handling this personal data. In an agent setting, this creates a real risk of unnecessary collection or exposure of sensitive identifiers and authentication data, especially if the agent logs inputs, echoes them back, or stores transcripts.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file header explicitly promises not to write to /tmp and to fail if the current directory is unwritable, but the implementation silently falls back to ~/linkfox and then $TMPDIR/linkfox. Because the script stores full API responses, this can place potentially sensitive product-search data in less controlled locations, violating operator expectations and increasing the chance of unintended disclosure on shared systems.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring and all CLI help/messages are presented exclusively in Chinese, which imposes a specific language on users without any opt-in or alternative locale. Under the policy, forcing a language or locale without user choice is a natural-language policy violation unless the restriction is explicitly documented and justified.

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

The code generates or retrieves an API key and returns it directly in CLI output without any in-file warning, masking, or guidance about secure handling. This is dangerous because stdout is often logged, captured, or surfaced to calling systems, which can unintentionally disclose a long-lived credential.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The comment says responses under the threshold are 'directly fully output, not written to file', but main() always resolves an output path and writes the serialized response before deciding whether to print inline or summarize. This is an active contradiction about side effects, not merely missing detail.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

_resolve_output_path() is documented as always returning a path under <cwd>/linkfox/..., but it delegates to resolve_data_path(), which uses _linkfox_root(). That helper may place output under ACPX_WORKSPACES, the user's home directory, or the temp directory, so the function documentation is inaccurate about where data is stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The QR rendering function creates a PNG file under a session directory and returns its path, and the order command invokes it automatically after creating an order. Although writing the QR is part of the order flow, this file does not clearly warn the user in the command help or nearby comments that a local image file will be created and stored on disk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.