Back to skill

Security audit

美客多选品数据

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real LinkFox Mercado Libre data-query skill, but it needs Review because it also handles credentials, account onboarding, payment orders, local storage, and automatic feedback reporting with weak safeguards.

Install only if you trust LinkFox with your Mercado research queries, account usage data, phone-based onboarding data, and billing workflow. Before use, avoid custom LINKFOX_* endpoint overrides, treat generated API keys as secrets, do not paste keys into shell history or shared logs, review any payment order before paying, and periodically delete local linkfox response/cache files if they may contain sensitive business data.

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

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:123
Finding

Silent Transmission of Conversation-Derived Feedback

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/linkfox_mercado_product_selection.py:38
Finding

Credentials and Session Metadata Can Be Redirected to Arbitrary Endpoints

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 ``` ```python def call_api(params): api_url = get_api_url() api_key = get_api_key() data = json.dumps(params).encode("utf-8") headers = { "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/2.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", ""), } req = Request( api_url, data=data, headers=headers, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` The onboarding script separately permits overrides for every authentication service: ```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") ``` Sensitive onboarding requests include phone numbers, SMS verification codes, access tokens, refresh tokens, user IDs, and generated API keys. ### T ...[truncated 2090 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:486
Finding

Generated API Key Is Exposed Through Standard Output and Shell Configuration Guidance

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 ``` The onboarding instructions then tell the agent to relay commands containing the complete key, including shell startup-file commands such as: ```bash echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc ``` ### Technical Analysis The login operation returns the complete generated API key as a JSON field and `_emit` prints the entire object to stdout. Standard output may be captured by: - Agent conversation transcripts. - Terminal scrollback. - CI/CD logs. - Process wrappers. - Shell redirection. - Audit or observability systems. The documentation further recommends placing the key directly in a shell command. This can expose it in shell history, process-monitoring output, backups, and plaintext shell startup files. An API key is a bearer credential and should be handled as a secret rather than normal command output. ### Attack Path 1. The user submits a phone number and SMS code to the onboarding command. 2. The script authenticates and obtains or generates an API key. 3. The complete API key is inserted into the return object. 4. ` ...[truncated 755 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/linkfox_mercado_product_selection.py:250
Finding

Unsanitized Session Identifier Allows Path Traversal and Writes Outside the Intended Directory

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) _ensure_meta(root, session_dir, date_str, sid, ts) return root, session_dir ``` The onboarding script contains the same unsafe construction: ```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 `SESSION_ID` is treated as a trusted directory name, but it can contain: - `..` traversal components. - Absolute paths. - Platform-specific path separators. - Drive letters or UNC paths on Windows. With `os.path.join`, an absolute final component can discard the preceding root. Traversal components can resolve outside the intended date and LinkFox directories. Subsequent functions create directories and write `_meta.json`, response JSON, index entries, or QR images beneath the resulting location. No canonicalization or containment check confirms that the resolved path remains un ...[truncated 1184 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/linkfox_mercado_product_selection.py:96
Finding

Complete API Responses Are Persisted in Insecure Cache and Temporary Locations

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
Finding

Runtime Guidance Installs Unpinned Third-Party 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 The script instructs users to install `qrcode`, `pillow`, and `requests` without pinned versions, hashes, a lock file, or a specified trusted package index. Installing the latest available package version makes the effective dependency code mutable after the Skill has been reviewed. This creates non-reproducible installations and increases exposure to upstream compromise, malicious package-index substitution, or incompatible future releases. The package names shown are not evident typosquatting attempts, and no malicious package source is embedded. The issue is therefore an insecure supply-chain practice rather than confirmed malicious dependency use. ### Attack Path 1. A user invokes onboarding on a system missing one of the optional dependencies. 2. The script instructs the user to run an unpinned `pip install` command. 3. Package resolution occurs against the user's configured Python index at that later time. 4. A compromised upstream release, hostile mirror, or dependency-chain package is selected. 5. Package installation executes build or installation logic under the user's account. 6. The compromised dependency subsequently executes when the onboarding script imports it. ### Impact Assessment A compromi ...[truncated 406 chars]
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 (30)

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

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The request destination is influenced by environment-controlled configuration via LINKFOX_TOOL_GATEWAY, and the request also includes sensitive headers such as the API key and session metadata. In an agent/runtime context, environment variables are often externally supplied, so a poisoned gateway value can redirect authenticated traffic to an attacker-controlled host and exfiltrate credentials or user data.

Content

Scanner excerpt · scripts/linkfox_mercado_product_selection.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 this code sends sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those endpoints. In a skill/runtime environment where environment variables may be influenced by a packager, wrapper, or compromised host, this enables silent credential exfiltration and redirection to attacker-controlled services.

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

The gateway URL is also built from environment-controlled configuration and used with an Authorization header carrying the user's API key. If an attacker can influence LINKFOX_AGENT_API_URL or fallback variables, requests can be redirected to a malicious server and the API key plus subsequent account/order operations can be captured.

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

The skill is described as a data-query tool, but the detected behavior includes authentication, API key lifecycle actions, account/team queries, package purchase flows, payment initiation, QR rendering, and order/payment status checks. These undisclosed account and payment capabilities materially expand the trust boundary and could expose users to unauthorized transactions, credential misuse, or sensitive account operations under the guise of analytics.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as a data-query tool, but the detected behavior includes authentication, API key lifecycle actions, account/team queries, package purchase flows, payment initiation, QR rendering, and order/payment status checks. These undisclosed account and payment capabilities materially expand the trust boundary and could expose users to unauthorized transactions, credential misuse, or sensitive account operations under the guise of analytics.

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

md
On PowerShell, wrap the JSON in single quotes the same way; if quoting is troublesome, write the payload to a file and pass it via `--inline` after loading, or use `ConvertTo-Json` to build the argument.

## Display Rules

1. Present the returned data clearly without inventing unsupported business conclusions.
2. Preserve the meaning and important field names from results; translate labels only when it improves readability.

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

This file implements SMS login, token acquisition, plan listing, ordering, and payment QR generation, which materially exceeds the declared skill purpose of Mercado product-selection data query and analysis. Scope expansion is dangerous because users invoking an analytics skill would not reasonably expect account onboarding, credential issuance, and commerce flows, increasing the chance of social engineering and unauthorized sensitive actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code can create orders and render payment QR codes, enabling billing actions unrelated to a product-selection analytics skill. In context, that makes the skill more dangerous because it can steer a user from benign data analysis into real financial transactions under the same trust boundary.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares capabilities that imply environment access, filesystem writes, and network access, but it does not define an explicit tool scope such as permissions or allowed-tools. That omission weakens least-privilege controls and makes it harder for reviewers or enforcement layers to constrain what the skill can access if the implementation changes or is misused.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The activation text uses broad, common shopping-analysis phrases that may cause the skill to trigger unintentionally in unrelated conversations. Overbroad triggering can lead to unnecessary network calls, paid API consumption, and unexpected handling of user data in contexts where the user did not intend to invoke this skill.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
## Core Concepts

- Call only `${LINKFOX_TOOL_GATEWAY}/mercado/productSelection`. Do not call the upstream XP-MCP server directly, and do not ask the user for upstream `secret-key` / `X-API-Key` — upstream credentials are owned by the backend.
- The request body is always `{"toolName":"...","arguments":{...}}`. The script takes this whole object as a single JSON argument.
- Field names inside `arguments` must match `references/mercado-tool-reference.md` exactly, including camelCase names such as `siteId`, `itemId`, `productId`, `categoryId`, `runDate`, `runMonth`, `pageNo`, `pageSize`.
- Read `data` first when presenting results. Read `contentText` when `data` is text or ambiguous. Show `rawResponse` only when the user asks for raw diagnostics.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs persistent storage of full API responses into the project directory but does not clearly warn users about local retention or privacy implications. Persisting potentially sensitive commercial, account, or usage data without prominent disclosure increases the risk of unintended exposure to other tools, collaborators, backups, or source control.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Mandating persistent local storage of complete responses in a session-organized directory creates a built-in data retention surface that can leak information over time. Even if the API data is not inherently secret, session grouping and raw response retention can reveal user interests, usage patterns, account details, and other metadata to anyone with filesystem access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

标题与整体说明直接以中文“参考”“调用规范”等形式呈现,未说明这是可选语言,也未提供其他语言选项。根据语言/locale 政策,若技能文档或指引默认强制特定语言而无用户 opt-in,属于自然语言层面的策略风险。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation states that responses are automatically written to disk and cached for 24 hours, with small responses fully printed and larger ones summarized, but it does not require sanitization, encryption, access controls, or operator warnings. Because API responses may contain business-sensitive query results, comments, usage information, or other user-supplied content, local persistence can create unintended data exposure on shared hosts, developer machines, or CI environments.

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

输出策略:响应体 ≤ 8 KB 时落盘后全量打印;> 8 KB 时落盘后只打印摘要(顶层字段、total/costToken 等计数、最大列表字段长度 + 前 3 条样本)。二次同参会走 24h 缓存,输出含 Cache hit。

curl 示例

bash
curl -X POST "${LINKFOX_TOOL_GATEWAY}/mercado/productSelection" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The documentation states that package usage is retrieved automatically from authentication context, but it does not clearly warn users that invoking the tool accesses account-linked usage data tied to their identity. This can lead to unintended disclosure of subscription/account metadata and weakens informed consent around authenticated data access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The reference instructs the skill to send requests to a production gateway at an external domain, but does not warn users that their queries and parameters leave the local agent environment and are transmitted to a third-party network service. In this skill context, users may submit commercially sensitive market research, seller, product, or account-related queries, so lack of disclosure creates a real data-exposure risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The onboarding instructions explicitly tell the operator to collect a user's phone number and use it in a scripted registration flow, but they provide no privacy notice, consent language, retention limits, or guidance on secure handling of the number and resulting authentication artifacts. In a support/onboarding context this creates a real privacy and account-security risk because agents may solicit sensitive personal data and process it through automation without clear safeguards.

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 presents usage and output behavior entirely in Chinese, and subsequent user-facing messages also use Chinese text. This creates a locale policy issue because the skill assumes a specific language without indicating that users can choose or opt in to that language.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level documentation states the full response is always written under <cwd>/linkfox/... and explicitly says writing to /tmp is forbidden and a non-writable current directory should cause an error. However, _linkfox_root() actually falls back from the workspace/current directory to ~/linkfox/ and then $TMPDIR/linkfox/, and _resolve_output_path() uses that fallback path. This is a clear mismatch between the documented storage behavior and the implemented behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The comment says small responses are 'directly fully output, not written to file', but main() still writes every response to out_path before deciding whether to print inline. Separately, the _linkfox_root() docstring says the root selection may fall back to ~/linkfox/ or $TMPDIR/linkfox/, which conflicts with the module docstring's claim that /tmp is forbidden and non-writable current directories should error. These are active contradictions in the file's own documentation about persistence behavior.

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

Natural-language strings and validation logic enforce a mainland China phone format, with area code +86 and Chinese-only user messaging, but the file does not present this as an explicit locale-restricted tool or offer opt-in language/locale selection. Under the stated policy, forcing a specific language or locale without user choice is a policy concern unless clearly documented and justified.

Content

No source excerpt is available for this finding.