Back to skill

Security audit

Seerfar-Ozon商品详情

Security checks for vulnerabilities and agentic risk

Overview

This Ozon product lookup skill performs the advertised lookup, but it also has automatic feedback reporting, broad credential and billing flows, and unsafe local/environment handling that users should review before installing.

Review this before installing. Use only in an environment where you trust LinkFox endpoints and can control LINKFOX_* environment variables. Do not provide SMS codes or create payment orders unless you intentionally want the LinkFox account/billing flow, avoid storing API keys in shell profiles, and inspect or clean the local linkfox output/cache directories after use. Automatic feedback reporting should be disabled or made opt-in before handling sensitive product research or account details.

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:135
Finding

Automatic External Feedback Reporting Without Explicit User Consent

Content
View full analysis
Remediation
View remediation

other

Warning
Location
scripts/seerfar_ozon_product_detail_search.py:62
Finding

Unnecessary Session and Execution Metadata Transmitted with Product Queries

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:68
Finding

Environment-Controlled API Origins Can Redirect Credentials and Personal Data

Content
View full analysis
str: for n in (name, *fallbacks): v = os.environ.get(n) if v: return v.rstrip("/") return default.rstrip("/") 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") ``` The product-query script has the same issue at `scripts/seerfar_ozon_product_detail_search.py:36-39`: ```python def get_api_base() -> str: return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") ``` Sensitive headers and requests are subsequently constructed at `scripts/onboarding.py:209-225`: ```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 ``` ### Technical Analysis Service origins are accepted directly from environment variables without validating: - The URL scheme. - The destination hostname. - The port. - Embedded credentials. - Whether redirects remain on the approved origin. The scripts then sen ...[truncated 1431 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/seerfar_ozon_product_detail_search.py:251
Finding

Path Traversal Through Unsanitized SESSION_ID

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 repeats the unsafe construction at `scripts/onboarding.py:153-160`: ```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 path component. It is not checked for: - `..` parent-directory traversal. - Forward or backward path separators. - Absolute paths. - Platform-specific drive or UNC prefixes. - Excessive length or special filesystem names. `os.path.join()` does not confine the result beneath the intended root. An absolute final component can discard preceding components, while traversal components can escape the session directory. Subsequent code creates directories and writes metadata, response files, and QR images under the resulting location. ### Attack Path 1. An attacker controls or influence ...[truncated 1029 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:478
Finding

API Credential Exposed Through Standard Output and Plaintext Shell Profiles

Content
View full analysis
dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return {"error": f"login: invalid phone format: {phone}", "phone": masked} if not re.fullmatch(r"\d{4,8}", code): return {"error": f"login: invalid verification-code format: {code}", "phone": masked} lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} if lg.get("is_new_user"): lbt = _login_by_token(lg["access_token"], lg["refresh_token"]) if "error" in lbt: print(f"{TAG} {lbt['error']}", file=sys.stderr) info = _fetch_user_info_v3(lg["access_token"], lg["user_id"]) if "error" in info: return {"error": info["error"], "phone": masked} tok = _get_or_generate_api_token(lg["access_token"], lg["user_id"], info["group_id"]) if "error" in tok: return {"error": tok["error"], "phone": masked} return { "api_key": tok["api_key"], "phone": masked, "group_id": info["group_id"], "member_id": info["member_id"], "source": tok["source"], "nick_name": lg.get("nick_name", ""), "team_name": info.get("team_name", ""), "is_new_user": lg.get("is_new_user", False), } def _emit(obj: dict) -> None: print(json.dumps(obj, ensure_ascii=False, indent=2)) ``` The onboarding documentation at `references/onboarding.md:10-15` directs users to place the resulting key in persistent shell startup configuration using commands equivalent to: ```bash echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc ``` ### Technical Analysis A successful login returns the complete A ...[truncated 1543 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:31
Finding

Unpinned Runtime Dependencies and Unsafe Installation Guidance

Content
View full analysis
dict: try: import qrcode except ImportError: return {"png_path": None, "ascii_qr": None, "error": "Missing QR rendering dependency"} ``` The runtime error guidance instructs users to install mutable package names such as `requests`, `qrcode`, and `pillow`, but the project contains no lockfile, pinned requirements file, or package hashes. ### Technical Analysis The Skill relies on third-party packages resolved at runtime without: - Exact version pins. - Cryptographic hashes. - A dependency lockfile. - A project-controlled installation manifest. - A restriction to a trusted package index. Package installation can execute package build or installation code. Mutable, unverified resolution increases exposure to compromised future releases, malicious custom indexes, dependency confusion, or incompatible packages. The displayed QR error string is an English representation of the dependency failure path; the dependency names and affected behavior match the audited source. ### Attack Path 1. The onboarding script detects that a dependency is unavailable. 2. The user follows the installation guidance. 3. The package manager resolves an uncontrolled version from its configured indexes. 4. A malicious index, compromised release, or substituted dependency supplies attacker-controlled package code. 5. Installation or import executes that code with the user's privileges. ### Impact Assessment Successful supply-chain exploitation can execute arbitrary code with the privileges of the user installing or running the Skill. This could expose environment vari ...[truncated 245 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/seerfar_ozon_product_detail_search.py:114
Finding

Sensitive Responses and Payment QR Data Persisted with Default Filesystem Permissions

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

Tainted flow: 'url' from os.environ.get (line 235, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The POST target URL is derived from environment-controlled base URLs, and the function sends sensitive authentication material such as access tokens, refresh tokens, API keys, phone numbers, and SMS codes to that destination. If an attacker can influence environment variables or deployment configuration, they can redirect these requests to attacker-controlled infrastructure and exfiltrate credentials or intercept login and payment-related flows.

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

The gateway request URL is also built from environment-controlled base configuration and is used with an Authorization header containing the agent API key. A malicious or compromised runtime can redirect the gateway call to an attacker server, causing credential leakage and unauthorized account, billing, or order actions.

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

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request headers and destination are influenced by environment variables, including LINKFOX_TOOL_GATEWAY and multiple metadata headers, and the script sends them directly over the network with an API key. In an agent/runtime context, environment variables are often attacker-influenced or cross-skill influenced, so this can exfiltrate credentials and session metadata to an arbitrary endpoint if the gateway variable is overridden.

Content

Scanner excerpt · scripts/seerfar_ozon_product_detail_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 ""

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims strict output and storage behavior, but the analyzed behavior includes undeclared local persistence, caching in additional locations, possible fallback to home/temp directories, and forwarding arbitrary JSON rather than enforcing SKU-only parameters. This mismatch creates confidentiality and integrity risks because sensitive API responses may be stored in unexpected places and the backend may receive unintended parameters.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims strict output and storage behavior, but the analyzed behavior includes undeclared local persistence, caching in additional locations, possible fallback to home/temp directories, and forwarding arbitrary JSON rather than enforcing SKU-only parameters. This mismatch creates confidentiality and integrity risks because sensitive API responses may be stored in unexpected places and the backend may receive unintended parameters.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger condition is intentionally broad enough to activate for general Ozon product-detail intent even when the user does not name this skill. Overbroad routing can cause unnecessary invocation of a paid, networked, data-persisting skill and increases the chance that user requests are sent to a third-party service without sufficiently specific intent.

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

md
3. **Read aggregates, then trend**: start with top-level `totalSales` / `dailySales` / `totalRevenue` / `stock` / `categoryRanks` for a snapshot, then drill into `salesTrendVOList` for the daily series.
4. **One SKU per call**: this endpoint takes a single `sku`; to compare products, call once per SKU.

## Display Rules

1. **Present data only**: show the product metrics in a clear layout without subjective advice.
2. **Lead with identity + snapshot**: `title`, `sku`, `price` (₽), `reviewRating` (`reviewCount` reviews, `questionsAndAnswers` Q&A), then the sales snapshot (`totalSales`, `dailySales`, `totalRevenue`, `stock`) and the window (`startDate`–`endDate`).

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 file implements account onboarding, SMS login, API-key issuance, package listing, purchasing, and order querying, none of which are necessary for an Ozon product-detail lookup skill. That mismatch is dangerous because it introduces credential collection and monetization capabilities unrelated to the declared skill purpose, strongly suggesting covert expansion of privileges and data access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The ability to create payable orders and render payment QR codes is unrelated to product-detail analysis and can directly trigger financial transactions. In the context of a search/analysis skill, this creates unjustified billing capability and materially increases the risk of unauthorized purchases, social engineering, or hidden monetization flows.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This code performs SMS-based login and retrieves or generates API tokens, enabling the skill to collect user phone numbers and verification codes and then mint reusable credentials. In a skill advertised as Ozon product-detail search, that is a severe overreach that can lead to account takeover, persistent unauthorized access, and downstream abuse of the user's LinkFox environment.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation explicitly says writing to /tmp is forbidden and non-writable current directories should cause an error, but the implementation silently falls back to home and temporary directories. This mismatch is dangerous because operators and calling agents may rely on the documented storage boundary, while data may actually be written to broader or less protected locations, including temporary storage.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill declares no explicit tool/permission scope even though it uses environment access, file writes, and network capabilities. Without a least-privilege declaration, the runtime may grant broader powers than users or reviewers expect, increasing the chance of unintended data access, persistence, or exfiltration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The API reference instructs callers to send an Authorization header and optional user identifiers (uId, memberId) to an external service but provides no privacy, minimization, or handling guidance. This creates a real data-protection risk because agents may forward identifiers and secrets without informing users, validating necessity, or constraining downstream use.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This documentation explicitly demonstrates posting data and an API credential to an external gateway, which is an actual external-transmission behavior rather than a false positive. In this skill's context, external calls are expected for functionality, but the lack of accompanying safeguards, scope restrictions, and disclosure makes the transmission more dangerous than a normal example alone.

Content

Scanner excerpt · references/api.md (reported line 158)May include surrounding context.

}

text

## curl 示例

```bash
curl -X POST https://tool-gateway.linkfox.com/seerfar/ozon/productDetailSearch \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The Feedback API sends free-form content to a separate endpoint, but the documentation does not warn that arbitrary user text may be transmitted externally. Because feedback content can easily include sensitive user data, prompts, business context, or secrets, omission of this warning increases the chance of unintended exfiltration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The onboarding flow instructs operators to collect and process a user's phone number and SMS verification code through a local script, but it provides no privacy notice, consent language, retention limits, or guidance on secure handling of that personal data. This creates a real privacy and security risk because users may disclose sensitive identifiers and one-time codes without understanding how they are stored, transmitted, or protected.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code file contains user-facing natural-language help and description text only in Chinese, including the module docstring and command descriptions. Under the language/locale policy, forcing a specific language without offering user choice or documenting a justified locale constraint is a policy violation.

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

The module docstring presents usage and output behavior entirely in Chinese, indicating the skill is designed to communicate in a fixed language. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless the constraint is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The comment claims small responses are printed directly without file persistence, but the implementation always writes the full response to disk first. This creates undeclared data retention and can surprise users or orchestrators that expect ephemeral handling for small outputs, leading to unintended storage of potentially sensitive commercial data.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script persistently stores full API responses, cache entries, and session metadata on local disk, even though the skill is described as a read/query tool for product-detail lookup. In agent environments, local persistence can retain sensitive business data, identifiers, and activity history beyond user intent, increasing exposure to other processes, users, or later tasks.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The output-path docstring claims results are stored under /linkfox, but the code may redirect storage to ACPX_WORKSPACES, the home directory, or the temp directory. This discrepancy weakens operator assumptions about where data resides and can cause accidental exposure through less monitored or shared filesystem locations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The document's operational instructions are presented only in Chinese, which can amount to forcing a specific language without user opt-in. The policy allows locale constraints when they are explicitly justified or optional, but no such choice or justification is provided here.

Content

No source excerpt is available for this finding.