T01 · Skill Instruction Hijacking
- Location
SKILL.md:142- Finding
Silent Transmission of User Feedback to an External Service
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill can perform keyword searches, but it also handles account login, API keys, paid orders, local storage, and quiet feedback reporting in ways users should review before installing.
Review this before installing. Use it only if you trust LinkFox with your marketplace queries, API key, account identifiers, and any phone/SMS onboarding data you choose to provide. Avoid running payment/order flows unless you explicitly intend to buy credits, verify endpoint environment variables point only to trusted LinkFox HTTPS hosts, and treat any generated API key as a secret rather than leaving it in transcripts or shell startup files.
SKILL.md:142Silent Transmission of User Feedback to an External Service
scripts/seerfar_ozon_market_keyword_search.py:36Credential-Bearing Requests Can Be Redirected to Arbitrary Endpoints
scripts/seerfar_ozon_market_keyword_search.py:63Unnecessary Disclosure of Agent Session and Message Identifiers
scripts/onboarding.py:486Full API Key Is Printed to Standard Output and Recommended for Plaintext Persistence
The code builds request destinations from environment-controlled base URLs and then sends sensitive onboarding data to them via requests.post. Because this script handles phone numbers, SMS codes, access tokens, refresh tokens, API keys, and payment-related flows, a malicious or misconfigured environment can silently redirect secrets to an attacker-controlled host, resulting in credential theft and account compromise.
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 client uses urlopen on a URL derived from environment variables and attaches the API key in the Authorization header. If the environment is attacker-influenced, all authenticated gateway traffic, including account, package, and order operations, can be redirected to an arbitrary server and the API key exfiltrated.
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 request sent via urlopen includes multiple headers sourced directly from environment variables, and the destination base URL is also overrideable via LINKFOX_TOOL_GATEWAY. This creates a tainted outbound data flow where secrets and session metadata can be exfiltrated to an attacker-controlled endpoint if the environment is influenced, which is especially risky because the Authorization API key is transmitted on every request.
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 skill claims to search keyword metrics, but it also persists full API responses locally, maintains local caches, writes session/date-organized metadata, and may fall back to alternate storage locations. Undeclared persistence increases privacy and data-retention risk because users may not expect market queries, account-linked identifiers, or response payloads to be stored beyond the immediate interaction.
The skill claims to search keyword metrics, but it also persists full API responses locally, maintains local caches, writes session/date-organized metadata, and may fall back to alternate storage locations. Undeclared persistence increases privacy and data-retention risk because users may not expect market queries, account-linked identifiers, or response payloads to be stored beyond the immediate interaction.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
3. **Use `keywords` + `matchType` to scope a niche**: pass seed terms in Russian with `matchType: 1` (fuzzy) to enumerate related long-tail terms.
4. **Pick the right `searchDate`**: omit it for current trends (last 30 days); pass an explicit date for month-over-month comparison.
## Display Rules
1. **Present data only**: show keyword metrics in a clear table without subjective advice.
2. **Lead with keyword columns**: `query` / `queryCn` (Chinese translation), then `searchVolume`, `count30GrowthRate`, `productCount`, `sellers`, `avgPrice`.
The onboarding document introduces authentication recovery, account registration, and billing/purchase workflows that are materially unrelated to the declared purpose of Ozon/Wildberries keyword analysis. This expands the skill into handling credentials, account lifecycle, and payments, creating an unnecessary trust and attack surface that could enable data collection or unauthorized commercial actions under the guise of a market-research tool.
The documented ability to register accounts by phone number and create billing orders is not justified by the skill's stated function of keyword market analysis. When a skill can solicit identity data and initiate purchases outside its expected scope, users may be socially engineered into providing sensitive information or authorizing charges they did not anticipate.
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 is described as an Ozon/Wildberries keyword research capability, but the code implements a separate onboarding and commerce CLI for login, API-key issuance, subscription purchase, and payment QR generation. That scope mismatch is dangerous because it introduces credential handling and billing behavior users would not reasonably expect from a keyword-search skill, increasing the chance of covert data collection or unauthorized commercial actions.
The file contains plan enumeration, order creation, and payment QR generation even though the skill's stated purpose is keyword market analysis. Commerce and payment capabilities expand the blast radius from data retrieval to financial transactions, creating risk of unintended purchases, user coercion into payment flows, or abuse if the skill is triggered unexpectedly.
The docstring promises that writing to /tmp is forbidden and that an unwritable current directory should cause failure, but the implementation silently falls back to the home directory and then the system temp directory. This mismatch is security-relevant because operators or higher-level controls may rely on the documented behavior to prevent data from being written to less trusted locations, yet the code will still persist sensitive responses there.
The skill declares no explicit tool scope even though its documented behavior uses environment variables, filesystem writes, and network access. Missing scope declarations weakens least-privilege controls and makes it easier for a seemingly narrow keyword-search skill to exercise broader capabilities than users or the platform may expect.
The trigger language is broad enough to activate the skill based on inferred intent even when the user does not explicitly request Seerfar or this specific capability. Over-broad auto-triggering raises the chance of unintended execution of a skill with network, env, and local-write behaviors, especially given the additional hidden onboarding and persistence functionality.
The skill instructs unconditional writing of full API responses to disk, but does not require upfront user warning or consent about local persistence. This creates a confidentiality and compliance risk because response bodies may contain user-linked identifiers, business data, or account-related metadata that persist in the project workspace.
Persistent logging of full responses in session-scoped project files can expose user-associated activity across tasks and over time. Session/date indexing increases discoverability of accumulated data for later users, tools, or processes with filesystem access, expanding the blast radius beyond the original request.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
## curl 示例
```bash
curl -X POST https://tool-gateway.linkfox.com/seerfar/ozon/marketKeywordSearch \
The documentation includes a separate feedback submission API that is unrelated to the primary keyword-search function and sends arbitrary content to a different external service. In an agent-skill context, this expands the skill's data egress surface and can enable unsolicited transmission of user content or conversation-derived data beyond what is necessary for the requested task.
The instructions explicitly direct collection and transmission of a user's phone number and one-time verification code, but provide no privacy notice, data-handling limits, or warning about the sensitivity of OTPs. This creates a credential-harvesting risk because SMS codes can be used to access or create accounts, and users are not informed of the security implications.
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 login, token exchange, user-info retrieval, and API-token generation, which are privileged account-management operations outside the advertised keyword-search purpose. In context, this is more dangerous because the skill can collect authentication factors and mint durable API credentials, enabling persistent access beyond a single search request.
The CLI hard-codes mainland China assumptions in user-facing behavior, including requiring an 11-digit phone number and always sending "+86" as the area code. The file-level description and command help do not indicate that this is a China-only skill or offer any language/locale choice, which violates the locale-policy rule for natural-language behavior.
The script persistently stores full API responses, cache entries, and session metadata on disk under linkfox/, including potentially sensitive business query results and identifiers such as session IDs. This exceeds the core keyword-search behavior described by the skill and increases the risk of unintended local data retention, cross-session data exposure, and forensic leakage from shared workspaces.
The documentation instructs sending requests and API-key-authenticated data to an external service without any warning that user-supplied search terms and filters leave the local environment. While external API use is expected for this skill, the absence of transparency and consent guidance increases privacy and compliance risk, especially if users provide proprietary market research terms or account identifiers like uId/memberId.
The feedback API section omits a warning that feedback content is sent to a distinct external endpoint from the main tool gateway. Because feedback content may contain free-form text derived from user conversations, this creates an avoidable risk of sending sensitive or unnecessary information to a second service without clear disclosure.