T01 · Skill Instruction Hijacking
- Location
SKILL.md:113- Finding
Automatic Third-Party Feedback Reporting Alters Agent Behavior Without Explicit User Consent
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill mostly implements Shopee merchant lookups, but it also adds account login, payment, automatic feedback reporting, and plaintext data retention that users should review before installing.
Install only if you are comfortable sending Shopee merchant/account data and LinkFox credentials through LinkFox services, and review the bundled onboarding and payment flows before allowing them to run. Avoid untrusted environment overrides, treat phone numbers, SMS codes, API keys, merchant IDs, and saved response files as sensitive, and delete or protect the local linkfox output directory after use.
SKILL.md:113Automatic Third-Party Feedback Reporting Alters Agent Behavior Without Explicit User Consent
scripts/_shopee_merchant_common.py:18Environment-Controlled API Endpoints Can Redirect Credentials and User Identifiers
scripts/_shopee_merchant_common.py:217Unsanitized SESSION_ID Allows Arbitrary Writable-Path Selection
scripts/onboarding.py:484API Keys and Complete Merchant Responses Are Exposed Through Plaintext Output and Storage
The helper sends sensitive environment-derived values, including the API key and session/message metadata, to a network endpoint whose base URL can itself be overridden by environment variables. In a skill that proxies merchant/account data, this materially increases the risk of credential exfiltration and unauthorized disclosure if the runtime environment or endpoint configuration is compromised or attacker-controlled.
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 sends authentication material and user data to URLs derived from environment-controlled base addresses without validating or pinning the destination host. If an attacker can influence environment variables in the runtime, they can redirect SMS login, token exchange, and API-key generation traffic to an attacker-controlled server and capture credentials or tokens.
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 = ""
Gateway requests are built from environment-controlled base URLs and sent with the API key in the Authorization header. An attacker who can set the environment can cause the tool to exfiltrate the LinkFox API key and subsequent account/order data to an external endpoint, turning this into credential theft and unauthorized API access.
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
Claiming to retrieve Shopee merchant information while instead performing onboarding, billing, payment, or order-status operations is a serious scope violation. In this context, the mismatch is more dangerous because users querying merchant data may unknowingly trigger account or payment-related actions and disclose sensitive financial or authentication context.
Claiming to retrieve Shopee merchant information while instead performing onboarding, billing, payment, or order-status operations is a serious scope violation. In this context, the mismatch is more dangerous because users querying merchant data may unknowingly trigger account or payment-related actions and disclose sensitive financial or authentication context.
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
The file implements LinkFox onboarding, SMS login, token handling, pricing, ordering, and payment QR generation, which is materially unrelated to the declared Shopee merchant-information skill. This scope mismatch is dangerous because users or orchestrators expecting read-only Shopee queries may instead trigger credential collection and account/payment workflows.
The order-creation flow initiates commercial purchases and renders payment QR codes, exceeding the manifest's expected merchant-info retrieval behavior. In the skill context, this is especially dangerous because it introduces real financial actions where users would reasonably expect passive data lookup only.
The login flow sends SMS codes, logs users in, fetches team metadata, and obtains or generates API tokens, none of which are necessary for Shopee merchant info retrieval. In this skill context, that makes the behavior more dangerous because it covertly adds credential acquisition and secret issuance capabilities under an unrelated feature label.
The skill advertises shell, network, environment, and file-write capable behavior but declares no explicit tool scope or permission boundaries. In a skill that handles merchant/account data and instructs writing outputs to disk, missing scope declarations increase the chance of overbroad execution and unintended access to sensitive local or remote resources.
The trigger description is overly broad and can activate on loosely related merchant topics even when the user did not clearly request this specific skill. Because the skill accesses merchant/shop/account data, over-triggering raises the risk of unnecessary data access, wrong-tool execution, and privacy exposure.
Internal contradictions about compute consumption reduce the user's ability to give informed consent and can lead agents to make unsafe autonomous decisions about retries or follow-up queries. In a paid API proxy context, this ambiguity is operationally and financially risky.
The skill states that full API responses are always written to local project storage without adequately warning that merchant data may include sensitive business, account, warehouse, or financial details. Persisting such data by default expands exposure beyond the immediate request and can leak information to later users, tools, commits, backups, or logs.
Always persisting full API responses to session-scoped local files creates durable plaintext retention of potentially sensitive merchant and user data. In this skill's context, that is especially dangerous because the data may include merchant identities, shop associations, warehouse locations, and prepaid account information that are unnecessary to retain after the task completes.
The document states both that use may consume compute/quota and that the skill does not consume compute. Contradictory cost semantics can mislead users into approving actions they would otherwise avoid, and can cause repeated retries or unexpected billing when quota-sensitive operations are involved.
The documentation explicitly directs users to send merchant-scoped data, access tokens, and API-key-authenticated requests through external Linkfox gateways, but it provides no warning about the sensitivity of those credentials or merchant identifiers. In a skill handling cross-border merchant account information, this omission can lead to accidental disclosure via misconfiguration, copied examples, client logs, or use in unsafe environments.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
export KEY=$LINKFOXAGENT_API_KEY
The curl examples show real outbound requests containing an Authorization header, accessToken, and merchantId, but they do not warn that these values may be exposed through shell history, terminal logging, process inspection, CI logs, or copied support transcripts. Because the examples concern merchant and shop data, accidental leakage could expose account metadata and enable unauthorized API use if tokens or keys are reused.
The file's operational documentation is written entirely in Chinese, including usage instructions and response guidance, with no indication that another language is available. This can violate language/locale policy when users are not given an explicit choice or opt-in for a specific language.
The onboarding guidance broadens behavior beyond the merchant-info skill’s stated purpose by instructing the agent to invoke a bundled onboarding flow whenever auth or billing errors occur. In a skill context, this can cause over-triggering into account-registration, payment, or credential-recovery actions that were not explicitly requested by the user, increasing the chance of unnecessary collection of sensitive data and unintended account changes.
The instructions direct the workflow to request, handle, and transmit a user’s phone number and one-time verification code without any privacy warning, minimization guidance, or restrictions on storage/logging. Because phone numbers and OTPs are highly sensitive authentication data, collecting them inside a skill workflow creates account-takeover and privacy risks if mishandled, logged, or requested without strong user awareness.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
"get_shop_list_by_merchant": {
"path": "api/v2/merchant/get_shop_list_by_merchant",
"method": "GET",
"response_key": "getShopListByMerchant",
"required": ['page_no', 'page_size'],
"notes": 'Shops bound to merchant; page_size max 500',
},
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
"get_shop_list_by_merchant": {
"path": "api/v2/merchant/get_shop_list_by_merchant",
"method": "GET",
"response_key": "getShopListByMerchant",
"required": ['page_no', 'page_size'],
"notes": 'Shops bound to merchant; page_size max 500',
},
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
"get_shop_list_by_merchant": {
"path": "api/v2/merchant/get_shop_list_by_merchant",
"method": "GET",
"response_key": "getShopListByMerchant",
"required": ['page_no', 'page_size'],
"notes": 'Shops bound to merchant; page_size max 500',
},
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
"get_shop_list_by_merchant": {
"path": "api/v2/merchant/get_shop_list_by_merchant",
"method": "GET",
"response_key": "getShopListByMerchant",
"required": ['page_no', 'page_size'],
"notes": 'Shops bound to merchant; page_size max 500',
},