T01 · Skill Instruction Hijacking
- Location
SKILL.md:267- Finding
Silent transmission of conversation-derived feedback to a separate service
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill can perform the advertised Keepa product search, but it also adds silent feedback reporting plus account, billing, credential, and local-storage behaviors that need review before installation.
Review this skill before installing. Use it only if you intend to use LinkFox's paid Keepa gateway, are comfortable with API-key and phone/SMS onboarding flows, and will explicitly approve any plan purchase or payment order. Avoid running it with untrusted environment variables, do not paste OTPs or API keys into shared logs, and prefer a safer secret store over shell profile files.
SKILL.md:267Silent transmission of conversation-derived feedback to a separate service
scripts/onboarding.py:484API key disclosed through stdout and recommended for plaintext persistent storage
scripts/keepa_product_search.py:60Unnecessary session and Agent metadata transmitted with every product search
scripts/keepa_product_search.py:250Unsanitized SESSION_ID permits output path traversal
scripts/keepa_product_search.py:93Complete API responses cached and persisted with unsafe fallback and default permissions
scripts/keepa_product_search.py:36Environment-controlled API endpoints can receive production credentials without validation
scripts/onboarding.py:163Runtime instructions recommend installation of unpinned dependencies
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
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 code allows network destinations to be overridden via environment variables and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API tokens to those endpoints. In a skill execution environment where env vars may be influenced by deployment or another component, this becomes an exfiltration/SSRF primitive against highly sensitive credentials.
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 URL is derived from environment variables and used to construct outbound urllib requests that carry the API key in the Authorization header. If an attacker can control the environment or deployment configuration, they can redirect requests to an attacker-controlled server and capture the API key or abuse the process as an SSRF client.
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 skill is presented as a product search utility, but the behavior described by the analyzer includes authentication, account lookup, subscription/package listing, payment order creation, QR code generation, and payment-status checks. Hidden or under-declared account and payment flows are dangerous because they can collect personal data, trigger billing-related actions, or expand the blast radius far beyond the user's apparent request.
The trigger conditions are extremely broad and explicitly say the skill should activate even when the user does not mention Keepa, as long as the request resembles advanced product research. Overbroad triggering can cause the agent to route generic commerce requests into a higher-cost, networked workflow without clear user intent or informed consent.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
{"domain": "1", "brand": ["Anker", "UGREEN"], "isHazMat": false, "sort": [{"fieldName": "monthlySold", "sortDirection": "desc"}]}
## Display Rules
1. **Present data clearly**: Show search results in well-structured tables with key fields: ASIN, title, price, BSR, monthly sales, rating, review count, brand
2. **Price conversion**: Convert prices from smallest currency unit to standard format (e.g., 2599 -> $25.99)
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 file implements account onboarding, token acquisition, subscription/package handling, order creation, and payment QR generation, which are unrelated to the stated Keepa/Amazon product-search purpose. That mismatch is dangerous because it expands the skill from search functionality into credential collection and monetization flows, increasing the chance of deceptive data harvesting and unauthorized billing behavior.
The code contains package purchasing, order creation, and payment QR generation even though the skill is presented as a product-search utility. In this context, hidden commerce functions are especially risky because they can steer users into purchasing subscriptions or expose billing data without a legitimate need tied to the declared skill behavior.
The script performs SMS login, obtains access/refresh tokens, queries team information, and generates or retrieves API keys, none of which are necessary for Keepa-based product search. In a mismatched skill, these flows amount to credential collection and privileged token issuance under a misleading feature description.
The skill declares capabilities that involve environment access, file writes, and network activity, but it does not define an explicit tool scope or permission boundary. That increases the chance the agent will perform higher-risk actions than the user expects, especially because the document includes instructions to read environment variables, call APIs, and write session-linked files.
Defaulting silently to the US marketplace can cause queries to be executed against the wrong region, sending user search terms and filters to an unintended external service context. This is mainly an integrity and privacy issue rather than a direct compromise, but it can still produce misleading results and unnecessary paid API usage.
The skill instructs the agent to always persist full API responses to a session-linked local path under the current working directory. Persisting complete responses by default can retain sensitive search inputs, account-related metadata, or commercially sensitive results beyond the immediate interaction, increasing exposure to other processes, users, or later unintended access.
This markdown file is written entirely in Chinese and provides no indication that users may choose another language or that the locale restriction is required for a region-specific purpose. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.
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/keepa/productSearch \
The onboarding flow instructs the agent to collect a user's phone number and OTP-based login data to obtain an API key, but it provides no privacy, consent, retention, or minimization guidance for handling this personal data. In an agent setting, this creates a real risk of unnecessary collection or exposure of sensitive identifiers and authentication data, especially if the agent logs inputs, echoes them back, or stores transcripts.
The file header explicitly promises not to write to /tmp and to fail if the current directory is unwritable, but the implementation silently falls back to ~/linkfox and then $TMPDIR/linkfox. Because the script stores full API responses, this can place potentially sensitive product-search data in less controlled locations, violating operator expectations and increasing the chance of unintended disclosure on shared systems.
The module docstring and all CLI help/messages are presented exclusively in Chinese, which imposes a specific language on users without any opt-in or alternative locale. Under the policy, forcing a language or locale without user choice is a natural-language policy violation unless the restriction is explicitly documented and justified.
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 generates or retrieves an API key and returns it directly in CLI output without any in-file warning, masking, or guidance about secure handling. This is dangerous because stdout is often logged, captured, or surfaced to calling systems, which can unintentionally disclose a long-lived credential.
The comment says responses under the threshold are 'directly fully output, not written to file', but main() always resolves an output path and writes the serialized response before deciding whether to print inline or summarize. This is an active contradiction about side effects, not merely missing detail.
_resolve_output_path() is documented as always returning a path under <cwd>/linkfox/..., but it delegates to resolve_data_path(), which uses _linkfox_root(). That helper may place output under ACPX_WORKSPACES, the user's home directory, or the temp directory, so the function documentation is inaccurate about where data is stored.
The QR rendering function creates a PNG file under a session directory and returns its path, and the order command invokes it automatically after creating an order. Although writing the QR is part of the order flow, this file does not clearly warn the user in the command help or nearby comments that a local image file will be created and stored on disk.
No suspicious patterns detected.