Back to skill

Security audit

Seerfar-Ozon关键词反查

Security checks for vulnerabilities and agentic risk

Overview

This skill performs the advertised Ozon keyword lookup, but it also handles account login, API key generation, billing, automatic feedback reporting, and broad local persistence in ways users should review before installing.

Install only if you are comfortable giving this skill LinkFox account/API credentials, allowing it to create payment orders when you request billing help, and storing full lookup responses locally. Avoid endpoint override environment variables unless you fully trust the destination, treat generated API keys as secrets, and review or disable automatic feedback reporting before use.

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

Error
Location
SKILL.md:152
Finding

Silent External Reporting of User-Derived Feedback

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/seerfar_ozon_keyword_back_search.py:36
Finding

Environment-Controlled Endpoints Can Receive API Keys and Authentication Tokens

Content
View full analysis
str: """Gateway base address: env LINKFOX_TOOL_GATEWAY first, production fallback.""" 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")) ``` Onboarding exposes the same pattern for more sensitive login endpoints: ```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") ``` ```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_ ...[truncated 3564 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:484
Finding

Generated API Key Is Exposed Through Standard Output and Plaintext Shell Profiles

Content
View full analysis
None: print(json.dumps(obj, ensure_ascii=False, indent=2)) 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} Successfully obtained API key (source: {r['source']})", file=sys.stderr) return 0 return 1 ``` The onboarding guide recommends persistent plaintext storage: ```markdown - Windows PowerShell (persistent): `setx LINKFOX_AGENT_API_KEY ""` - macOS zsh: `echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc` - Linux bash: `echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc` ``` ### Technical Analysis The login command includes the complete generated API key in the object passed to `_emit()`, which serializes it to stdout. Standard output may be retained by terminal capture, Agent tool logs, CI systems, shell wrappers, support diagnostics, or session recording systems. The documentation then recommends writing the secret directly into globally loaded plaintext shell initialization files. Such files are often backed up, synchronized, included in diagnostic archives, or readable by other software operating under the same account. ### Attack Path 1. T ...[truncated 883 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/seerfar_ozon_keyword_back_search.py:250
Finding

Unsanitized Session Identifier Enables Output Path Traversal

Content
View full analysis
str: """Prefer env SESSION_ID; otherwise generate HHMMSS-<6 hex>.""" 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]: """Return (linkfox_root, session_dir); session_dir always exists.""" 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 an equivalent path 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 incorporated into a filesystem path without rejecting: - Absolute paths. - `..` traversal components. - Platform-specific path separators. - Drive prefixes on Windows. - Existing symlinks that redirect the final path. With Python’s path semantics, an absolute final component can replace the preceding root. Traversal components can also escape the intended date and LinkFox directories after path normalization. The ...[truncated 1159 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/seerfar_ozon_keyword_back_search.py:96
Finding

Complete API Responses Are Duplicated in Plaintext and May Be Written to a Temporary Directory

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:162
Finding

Onboarding Recommends Unpinned Runtime Dependency Installation

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 onboarding script recommends installing third-party packages without: - Exact version pins. - Cryptographic hashes. - A lockfile. - An isolated virtual environment. - A documented trusted package index. As a result, package behavior can change after the Skill has been audited. Installation also executes package build and installation logic with the privileges of the user running `pip`. No evidence was found that the named packages are intentionally malicious. The risk arises from unconstrained future package resolution and installation. ### Attack Path 1. The user runs onboarding in an environment where `requests`, `qrcode`, or `pillow` is unavailable. 2. The script instructs the user to run an unpinned `pip install` command. 3. pip resolves whatever versions are currently available from the configured package index. 4. A compromised index, account takeover, malicious mirror, or future compromised release supplies unsafe code. 5. Package installation or later import executes that code with the user’s privileges. ### Impact Assessment A compromised dependency could access all files, credentials, environment variables, and network resources available to the invoking user. This includes the LinkFox API key and authentication tokens handled by onboarding. The c ...[truncated 176 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (21)

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 builds destination URLs from environment-controlled base URLs and then sends sensitive data to them via requests.post. Because this script handles phone numbers, SMS codes, access tokens, refresh tokens, generated API keys, and user/team identifiers, a malicious or misconfigured environment can redirect authentication traffic to an attacker-controlled server and exfiltrate 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
93% confidence
Finding

The gateway request path uses a Request/urlopen flow where the base URL is also taken from environment variables, while attaching the Authorization API key header. This creates an SSRF/credential-exfiltration primitive: an attacker controlling the runtime environment can redirect paid account, package, and order requests to an arbitrary server and capture the API key and business data.

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

The request headers and destination are influenced by environment variables, including LINKFOX_TOOL_GATEWAY and multiple metadata headers, and the code sends the API key to whatever base URL is configured. In an agent/runtime context where environment variables may be attacker-controlled or less trusted than hardcoded configuration, this can exfiltrate the credential and request data to an arbitrary endpoint via SSRF-like redirection.

Content

Scanner excerpt · scripts/seerfar_ozon_keyword_back_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 documented purpose is SKU-based Ozon keyword reverse lookup, but the skill also describes account login, SMS verification, API key generation, subscription management, payment order creation, payment-status polling, and QR-code file generation. This is a major capability expansion into authentication and billing flows, creating risk of credential handling, unauthorized purchases, privacy exposure, and user deception because the real behavior is materially broader than advertised.

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

md
3. **Split organic vs ad with `type`**: pass `["0"]` or `["1"]` to focus a listing-optimization pass (organic) or an ads pass (ad), then bound `naturalRank` / `adRank` to qualify positioning — these filter on the values surfaced in each row's `dimension`.
4. **Use `includeKeywords` / `excludeKeywords` to steer**: force in must-have modifiers and strip noise without running a second query.

## Display Rules

1. **Present data only**: show reverse-looked-up keyword metrics in a clear table without subjective advice.
2. **Lead with keyword columns**: `query` / `queryCn` (Chinese translation), then `searchVolume`, `count30GrowthRate`, `productCount`, `sellers`, `avgPrice`; show `dimension.naturalRank` and `dimension.type` (organic/ad) to convey how the SKU ranks for each term.

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

The file implements an onboarding, login, token-issuance, and billing CLI even though the declared skill is for Ozon SKU reverse keyword search. This mismatch is dangerous because it expands the skill's privilege and data-collection scope far beyond user expectations, increasing the risk of credential harvesting and unauthorized account/payment actions under the guise of unrelated functionality.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This code actively performs SMS login, retrieves user/team metadata, generates API tokens, and supports ordering and payment flows instead of keyword analysis. In the context of a search-analytics skill, these capabilities are unjustified and materially increase the chance of deceptive credential collection, token minting, and unauthorized monetization workflows.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill appears to require environment access, file writes, and network calls but declares no explicit tool scope or permissions boundary. In an agent setting, missing scope declarations weakens least-privilege controls and can allow a nominally narrow analytics skill to access broader local or remote resources than users expect.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to always persist full API responses to local session-organized files by default, and the schema explicitly includes user-linked fields such as uId and memberId. Default full-response logging increases the chance of retaining sensitive business data, identifiers, or account-linked metadata longer than necessary, especially when written into the working directory where other tools or users may access it.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The display rules explicitly require showing queryCn as a Chinese translation and frame output behavior around Chinese-language presentation, while the document as a whole mixes languages. There is no opt-in or user-choice mechanism for language/locale, which can violate a policy requiring language selection rather than forcing one locale.

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

}

text

## curl 示例

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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The onboarding flow explicitly instructs the agent to collect a user's phone number and use a local script to send verification codes and register/log in, but it provides no privacy notice, consent language, retention limits, or handling safeguards for that personal data. This creates a real privacy and security risk because users may be prompted to disclose sensitive contact information to an agent-mediated workflow without clear disclosure of how the number is used, stored, or protected.

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 user-facing CLI help/messages are written in Chinese, which imposes a specific language on users. The file does not offer any language selection, fallback, or justification that this is a China-specific or Chinese-only tool.

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

Embedding order creation, payment URL handling, and QR-code rendering in a keyword reverse-search skill is not justified by the declared business purpose. This creates an unnecessary payment surface that could be abused for deceptive charging, phishing-like payment redirection, or social engineering, especially when paired with the broader skill-purpose mismatch.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documentation explicitly says writing to /tmp is forbidden and an unwritable current directory should cause an error, but the implementation falls back to home and temporary directories. This mismatch can cause sensitive API results and session metadata to be written into less controlled locations, including shared temporary storage, undermining operator expectations and data-handling guarantees.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes a skill for reverse-looking up Ozon/Wildberries search keywords by SKU and returning market-profile data. Lines L260-L280 document an additional POST capability to submit feedback to a different external endpoint, which is not necessary to perform keyword back search itself and represents an extra network-facing capability outside the stated user-facing purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script persistently writes full API responses, cache entries, and session metadata to local storage even though the skill description is focused on keyword reverse-search and does not disclose durable local retention. These responses may contain commercially sensitive search intelligence, user query data, identifiers, or account-scoped results, creating unnecessary data-at-rest exposure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The comment for SMALL_THRESHOLD says responses at or below the threshold are output directly and not written to a file. In main, the script always resolves an output path and writes the serialized response before deciding whether to print full JSON or only a summary.

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 documents a fixed <cwd>/linkfox/... destination, yet it delegates to resolve_data_path, which uses _linkfox_root; that function may choose ACPX_WORKSPACES, the home directory, or the temp directory instead. This is an active contradiction about where data is stored.

Content

No source excerpt is available for this finding.