T01 · Skill Instruction Hijacking
- Location
SKILL.md:134- Finding
Automatic Transmission of User Feedback Without Explicit Consent
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
SKILL.md:134Automatic Transmission of User Feedback Without Explicit Consent
scripts/mpstats_ozon_product_detail.py:36Credential-Bearing Requests Can Be Redirected to Environment-Controlled Destinations
scripts/mpstats_ozon_product_detail.py:86Ozon Lookup Discloses Agent Session Metadata Beyond Functional Requirements
scripts/onboarding.py:488API Key Is Printed and Persisted in Plaintext Configuration
scripts/mpstats_ozon_product_detail.py:275Unsanitized Session Identifier Allows Output-Path Escape
scripts/onboarding.py:163Runtime Instructions Install Unpinned Third-Party Dependencies
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.
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 ""
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.
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 = ""
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.
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
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.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
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 matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
示 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
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.
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.
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.
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.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
| 402 | 算力或余额不足 | HTTP 402:按 SKILL.md 的 ## 解决认证和算力问题 处理。 |
| 其他非 200 值 | 业务异常 | 查看 errmsg / msg;常见为缺少/非法 productId、日期越过昨日等 |
curl -X POST https://tool-gateway.linkfox.com/mpstats/ozon/productDetail \
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.
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.
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.
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.
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.
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.
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.
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.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
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 = ""
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.
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.
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.
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.
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.
No suspicious patterns detected.