Back to skill

Security audit

MPSTATS-Ozon商品详情

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs the advertised Ozon product lookup, but it also includes sensitive onboarding, credential, billing, storage, and automatic feedback behaviors that need review before use.

Install only if you are comfortable with LinkFox handling product queries and related account/billing workflows. Before use, verify endpoint environment variables are not overridden, avoid sharing SMS codes unless you intend to register or log in, avoid storing API keys in shell startup files, and review any payment order before scanning or opening a QR code. Treat local linkfox output folders as potentially sensitive because they may contain full API responses and payment artifacts.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (6)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:134
Finding

Automatic Transmission of User Feedback Without Explicit Consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mpstats_ozon_product_detail.py:36
Finding

Credential-Bearing Requests Can Be Redirected to Environment-Controlled Destinations

Content
View full analysis
str: """Gateway base address: the environment override takes priority.""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") ``` ```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 implementation independently permits overrides for every sensitive 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") ``` Credential-bearing requests are then sent to those values: ```python headers = {"Authorization": _api_key()} req = Request(url, method=method, data=body_bytes, headers=headers) with urlopen(req, timeout=30) as resp: retu ...[truncated 1873 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/mpstats_ozon_product_detail.py:86
Finding

Ozon Lookup Discloses Agent Session Metadata Beyond Functional Requirements

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:488
Finding

API Key Is Printed and Persisted in Plaintext Configuration

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} API key obtained successfully", file=sys.stderr) return 0 return 1 ``` The onboarding documentation then recommends persistent plaintext storage: ```shell 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 `_emit(r)` serializes the entire login result, including the full API key, to standard output. In Agent and automation environments, stdout is frequently recorded in transcripts, CI logs, command logs, or observability systems. The documentation further recommends storing the key in shell startup files or the Windows user environment. Shell startup files are plaintext, may be backed up or synchronized, and are readable by any process with the user's file permissions. The commands can also remain in shell history. ### Attack Path 1. The user authenticates with a phone number and SMS code. 2. The onboarding flow obtains or generates an API key. 3. The full key is emitted to stdout as JSON. 4. An Agent transcript, terminal capture, CI log, or monitoring service records the output. 5. The user follows the documentation and stores the key in a plaintext startup file. 6. An ...[truncated 492 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mpstats_ozon_product_detail.py:275
Finding

Unsanitized Session Identifier Allows Output-Path Escape

Content
View full analysis
str: """Prefer SESSION_ID from the environment.""" 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 repeats the pattern: ```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 even though it comes from the execution environment. Values containing `..`, path separators, or an absolute path can cause `os.path.join` to resolve outside the intended LinkFox storage root. Subsequent functions create directories and write metadata, complete API responses, or QR images beneath the escaped path. Timestamped filenames reduce the likelihood of overwriting an existing file, but they do not preserve the intended filesystem boundary. ### Attack Path 1. An attacker controlling the parent process or environme ...[truncated 808 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
Finding

Runtime Instructions Install Unpinned Third-Party Dependencies

Content
View full analysis
dict: try: import qrcode except ImportError: err = "Missing qrcode dependency; run: 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("Missing requests dependency; run: pip install requests") ``` ### Technical Analysis The runtime error messages recommend installing mutable package names without exact versions, hashes, a lockfile, or a trusted package-index restriction. Installation therefore depends on the current state and configuration of the Python package index. The package names are established projects rather than observed typosquatting attempts, and the script does not automatically execute `pip`. Nevertheless, following these instructions can install unreviewed future versions or packages from a maliciously configured index. ### Attack Path 1. The environment lacks `requests`, `qrcode`, or `pillow`. 2. The onboarding script displays an installation command. 3. The user runs the command in an environment configured to use a compromised or attacker-controlled package index, or after an upstream compromise. 4. `pip` downloads and installs packages without hash verification. 5. Package installation or later import executes attacker-controlled code with the user's privileges. ### Impact Assessment A compromised dependency can execute arbitrary Python code with the privileges of the user running the installation or Skill. This can expose credentials, files, and network access available to that account. Exploitation requires a compromised dependency source, package releas ...[truncated 99 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 (27)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request destination and headers are partially derived from environment variables, including LINKFOX_TOOL_GATEWAY and multiple session identifiers, and the code sends them directly over the network. If an attacker can influence the runtime environment, they can redirect requests to an attacker-controlled host and exfiltrate the API key and session metadata, which is a real SSRF/credential-leak risk in agent execution environments.

Content

Scanner excerpt · scripts/mpstats_ozon_product_detail.py (reported line 105)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
90% confidence
Finding

The POST destination is derived from environment-controlled base URLs, so an attacker who can influence the runtime environment can redirect login and token-generation traffic to an arbitrary host. Because these requests carry SMS login data, access tokens, refresh tokens, and generated API keys, this creates a credential-exfiltration and SSRF-style risk rather than a harmless configuration choice.

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

The gateway request target is built from environment-derived base URLs and then used in urlopen with an Authorization header carrying the API key. If the environment is manipulated, requests can be redirected to attacker-controlled infrastructure, exposing credentials and enabling unintended outbound requests to internal or arbitrary systems.

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 declared purpose is a product-detail lookup, but the detected behavior includes phone-based authentication, API-key retrieval, account/team info access, subscription-plan listing, paid order creation, QR-code payment flows, and payment-status polling. This is a severe capability mismatch that can mislead users into authorizing account, credential, or billing actions unrelated to the expected MPSTATS/Ozon query, enabling hidden data collection or unauthorized purchases.

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
2. **Detail vs trend**: This endpoint is a **period aggregate** per SKU; for day-by-day time-series on a single SKU, use `mpstats-ozon-product-trend`.
3. **Detail vs drill-downs**: When the input dimension is a brand / category / seller (not a single SKU), prefer `brand-products` / `category-products` / `seller-products` — they already return aggregated metrics per SKU under that dimension.

## Display Rules

1. **Compact table** — lead with `productId`, `title`, `price`, `monthlySalesUnits`, `monthlySalesRevenue`, `rating`, `reviewCount`, `balance`, `deliveryScheme`, `firstDate`. Pull `revenuePotential` / `lostProfit` / `lostProfitPercent` in when the user asks about stock-out impact.
2. **Currency** — Ozon native currency is **RUB**; the `currency` field carries the symbol. Do not silently relabel.

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 skill claims to provide Ozon single-SKU detail lookup, but the included code instead implements account onboarding, SMS login, API key issuance, package listing, ordering, and payment flows. That mismatch is a strong indicator of deceptive scope expansion and materially increases the chance that the skill is harvesting credentials or monetizing access outside its stated purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Payment and order-creation capabilities are unrelated to a product-detail lookup skill and can induce users to authorize purchases they did not expect. In this context, billing code is especially dangerous because it is bundled into a data-retrieval skill, making the behavior misleading and out of scope.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
80% confidence
Finding

The skill describes capabilities that involve reading environment variables, writing files, and making network requests, but it declares no explicit tool scope or permissions boundary. In an agent setting, this weakens least-privilege controls and can allow the skill to access credentials, persist sensitive data locally, or call unintended external services without clear user or platform visibility.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger instructions say to activate the skill even when the user does not explicitly mention MPSTATS, based on a broad intent match. Over-broad auto-triggering increases the chance that the agent invokes a costly or side-effecting skill in situations where the user only asked a general question, which is especially risky given the skill's hidden authentication and payment-related behavior.

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

| 402 | 算力或余额不足 | HTTP 402:按 SKILL.md 的 ## 解决认证和算力问题 处理。 | | 其他非 200 值 | 业务异常 | 查看 errmsg / msg;常见为缺少/非法 productId、日期越过昨日等 |

curl 示例

bash
curl -X POST https://tool-gateway.linkfox.com/mpstats/ozon/productDetail \

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The onboarding document expands a single-SKU Ozon lookup skill into account recovery, registration, and billing workflows that are outside the stated purpose of the skill. This scope drift increases attack surface and can cause the agent to solicit credentials, phone numbers, or payment actions in contexts where users only expected a product-detail lookup.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document instructs the agent to facilitate phone-based registration/login and plan purchase flows, which are unjustified by the skill's stated data-query purpose. In an agent setting, this can be abused for social engineering, unauthorized account creation, or steering users into paid transactions under the guise of a simple marketplace lookup.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The guide tells the agent to ask for a user's phone number and use it to send a code and log in, but provides no privacy notice, consent language, retention limits, or data-handling constraints. Collecting personal contact information and OTP-related workflow data without safeguards creates privacy, compliance, and account-security risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The billing instructions let the agent create orders and display payment artifacts without a clear upfront warning that this may initiate a chargeable transaction. In practice, this can mislead users into unintended purchases or let a compromised/over-permissive agent trigger payment flows unrelated to the original product-detail request.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Although the skill is described as a single-SKU lookup, it persistently stores full API responses plus session metadata to local files by default. This creates unnecessary data retention and expands exposure of potentially sensitive commercial data, user activity traces, and identifiers beyond what is needed to answer the query.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation states that writing to /tmp is forbidden and that failure to write the current directory should be treated as an error, but the implementation silently falls back to the home directory and temp directory. This discrepancy can cause data to be written to less trusted or unexpected locations, undermining operator expectations and potentially exposing stored responses to other local users or tooling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code forwards SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME from the environment to the external API without any minimization or user-facing disclosure. In agent platforms, these values can reveal internal workflow structure or correlate user actions across systems, so transmitting them by default increases privacy and metadata-leakage risk.

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 before deciding what to print, but it does not require explicit consent or provide a clear warning that data will be persistently stored. In a skill context, users may expect a transient lookup, so unconditional storage increases the risk of accidental retention and later disclosure of business-sensitive data.

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

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code performs SMS-based login and API key generation, which far exceeds the permissions needed for querying a single Ozon SKU. In the context of this manifest, collecting phone numbers, verification codes, tokens, and issuing API keys is an unjustified credential-acquisition flow that could be used for account takeover or unauthorized access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The login flow only accepts 11-digit phone numbers and always uses area code +86, which enforces a specific locale in the natural-language behavior of the skill. The file does not offer user opt-in or clearly justify this region-specific restriction, so it appears to violate the language/locale policy criterion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The function retrieves or generates API tokens and returns them directly in output without any built-in guardrails, masking, or warning about handling sensitive credentials. In a skill environment, this increases the chance of accidental exposure through logs, transcripts, downstream tool chaining, or user copy/paste.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The file states that titles are returned in Russian and should be translated only on demand for Chinese or English users. This creates a default language behavior without explicit user opt-in, which can violate language/locale choice expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The document instructs use of an Authorization header sourced from environment variables but does not warn that the API key is sensitive or should never be logged, echoed, or included in examples/output. In agent/tooling environments, missing secrecy guidance can lead to accidental credential disclosure through debug logs, traces, or copied curl commands.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.