Back to skill

Security audit

沃尔玛-商品搜索

Security checks for vulnerabilities and agentic risk

Overview

The skill performs Walmart search, but it also handles sensitive LinkFox login, API keys, billing, feedback reporting, and persistent local storage with under-scoped controls.

Review this skill carefully before installing. It is not just a Walmart search helper: it may ask for a phone number and SMS code, print and persist an API key, create paid LinkFox orders, send feedback to LinkFox, and store full search results locally. Only use it if you trust LinkFox, understand the credit cost, keep endpoint environment variables controlled, and are comfortable with the local data and credential handling.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/walmart_search.py:34
Finding

Environment-controlled Walmart gateway can receive the API key

Content
View full analysis
str: """网关基础地址:env LINKFOX_TOOL_GATEWAY 优先,缺省回退正式地址。""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") def get_api_url(): sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "_shared")) return get_api_base() + API_PATH def get_api_key(): """ 获取配置在环境变量的API Key。 如果获取不到,按 SKILL.md 的 **## 解决认证和积分问题** 处理。 """ key = os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get("LINKFOXAGENT_API_KEY") if not key: print( "API Key 未配置", file=sys.stderr, ) sys.exit(1) return key 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", ""), "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")) ``` ### Technical Analysis The script permits `LINKFOX_TOOL_GATEWAY` to replace the trusted LinkFox gateway without validating the URL scheme or hostname. It then unconditionally attaches `LINKFOX_AGENT_API_KEY` or `LINKFOXAGENT_API_KEY` to the `Authorization` header. Sending an API credential to the legitimate LinkFox gateway is necessary for the declared Walmart search function. Allowing an arbitrary environment-selected des ...[truncated 1098 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:67
Finding

Configurable onboarding endpoints can receive phone credentials and access tokens

Content
View full analysis
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 _http_post(url: str, body: dict, headers: dict, timeout: int = 30) -> dict: """通用 requests POST,返回 JSON 或 {_error, _body}。""" try: _require_requests() except RuntimeError as e: return {"_error": str(e)} try: r = requests.post(url, json=body or {}, headers=headers, timeout=timeout) return r.json() ``` ```python def _login_v3(phone: str, code: str, channel: str) -> dict: resp = _login_post("/user/v3/web/login", { "type": "sms", "method": "login", "systemId": "LinkFoxAgent", "data": {"areaCode": "+86", "authPhone": phone, "authCode": code, "sourceChannel": channel or "skill"}, }) ``` ```python def _login_by_token(access_token: str, refresh_token: str) -> dict: """新用户送积分。失败不阻断。""" resp = _http_post(f"{_agent_user_base()}/account/loginByToken", { "token": access_token, "refreshToken": refresh_token, "device": {"aid": "3026344186", "did": "", "type": "Windows", "os": "10", "model": "149.0.0.0", "brand": "Chrome"}, }, _headers("agent-linkfox-web", "agent.linkfox.com", access_token=access_token)) ``` ```python def _fetch_user_info_v3(access_token: str, user_id: str) -> dict: """从 userInfo 拿 group_id / member_id。""" resp = _http_post(f"{_login_base()}/linkFoxApp/api/userCenter/userInfo", {}, _headers("agent-linkfox-web", "agent.linkfox.com", access_token=access_token, user_id=user_id)) ``` ```python ...[truncated 2489 chars]
Remediation
View remediation

other

Warning
Location
SKILL.md:164
Finding

Automatic feedback reporting can disclose user conversation content without explicit consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:483
Finding

Generated API key is emitted in plaintext to standard output

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} 成功获取 API key(来源: {r['source']})", file=sys.stderr) return 0 ``` The associated onboarding instructions also recommend plaintext persistence: ```text echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc ``` ### Technical Analysis `login_and_get_key()` returns the complete generated API key, and `_cmd_login()` serializes the entire object to standard output. Standard output is commonly captured by Agent transcripts, terminal scrollback, command runners, CI logs, orchestration platforms, and debugging systems. The documented configuration commands additionally encourage users to place the key directly in shell startup files. Those files are persistent plaintext storage and may be exposed through backups, support bundles, dotfile repositories, or overly broad local permissions. ### Attack Path 1. A user completes SMS authentication using the onboarding command. 2. The workflow retrieves or generates a LinkFox API key. 3. `_cmd_login()` prints the full key to standard out ...[truncated 625 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/walmart_search.py:92
Finding

Search queries and full API responses are persistently stored without restrictive permissions or cleanup

Content
View full analysis
CACHE_TTL_SEC: return None try: with open(path, encoding="utf-8") as f: payload = json.load(f) if isinstance(payload, dict): payload.setdefault("_cache", {})["hit"] = True return payload except (OSError, json.JSONDecodeError): return None def _save_cache(path, payload): try: with open(path, "w", encoding="utf-8") as f: json.dump(payload, f, ensure_ascii=False, indent=2) except OSError: pass ``` ```python serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = int(time.time()) out_path = _resolve_output_path(ts) try: with open(out_path, "w") as f: f.write(serialized) print(f"Saved full response: {out_path} ({len(serialized)} bytes)") if result.get("_cache", {}).get("hit"): print(f"Cache hit: {cache_path}") except OSError as e: print(f"Failed to save to {out_path}: {e}", file=sys.stderr) ``` ### Technical Analysis The script always writes the complete API response and may also cache it. Files and directories are created with permissions inherited from the process umask rather than explicit restrictive modes. The root-selection logic may place files in a workspace, home directory, or temporary directory. Although cache entries are treated as stale after 24 hours, stale files are not deleted. Session response files have no retentio ...[truncated 1080 chars]
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
94% confidence
Finding

The code sends authentication tokens and other sensitive data to URLs derived from environment-controlled base endpoints via requests.post. If an attacker can influence LINKFOX_LOGIN_API_URL or LINKFOX_AGENT_USER_API_URL, they can redirect SMS login credentials, access tokens, refresh tokens, and generated API keys to attacker-controlled infrastructure, causing credential exfiltration and account compromise. The mismatch between the skill’s declared Walmart-search purpose and this onboarding/payment behavior makes the data flow especially suspicious.

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 uses urllib.request.urlopen against a URL built from environment-controlled base configuration and includes the Authorization header from LINKFOX_AGENT_API_KEY. If the gateway base URL is tampered with, the skill will transmit API credentials and billing/order operations to an attacker-controlled server, enabling token theft, fraudulent order manipulation, or surveillance of account activity. In the context of a Walmart listing/search skill, this hidden payment/auth gateway is unrelated and therefore more dangerous.

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 72, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request sent to the network includes multiple headers sourced directly from environment variables, and the destination base URL is also controllable via LINKFOX_TOOL_GATEWAY. In an agent/runtime context, this can leak sensitive session metadata and the API key to an attacker-controlled endpoint if the environment is influenced, making the tainted flow a real exfiltration risk rather than a mere implementation detail.

Content

Scanner excerpt · scripts/walmart_search.py (reported line 79)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

This is a severe description-behavior mismatch: the skill claims to perform Walmart listing search, but analysis indicates it also supports login flows, API key generation, account/team data access, subscription plan listing, payment order creation, QR code generation, and payment-status queries. Hidden authentication and billing functionality creates a strong risk of credential harvesting, unauthorized account actions, and unexpected charges, especially because the skill text normalizes handling API keys, quota issues, and充值/payment flows.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger conditions are overly broad and explicitly instruct activation even when the user does not clearly ask for Walmart search. Over-broad routing increases the chance that the skill runs in unintended contexts, which becomes more dangerous here because the skill appears to include hidden auth/billing behavior and can consume paid credits.

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

{"keyword": "running shoes", "minPrice": 30, "maxPrice": 80, "sort": "best_match"}

text

## Display Rules

1. **Present data clearly**: Show search results in well-structured tables with key fields (title, price, rating, reviews, seller). Do not add subjective buying recommendations unless the user asks for analysis.
2. **Price formatting**: Always display prices with the currency symbol. When `wasPrice` is present, show both current and original prices to highlight discounts.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The onboarding document introduces account authentication, phone-based registration, and billing/payment workflows that are unrelated to the skill's declared Walmart product search purpose. This expands the skill's effective capability into credential handling and commerce flows, increasing the attack surface for phishing, unauthorized data collection, and abuse if triggered in the wrong context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The document explicitly instructs collection of a user's phone number, sending verification codes, logging in, and purchasing plans, none of which are justified by a Walmart search skill. In this context, these flows can normalize sensitive-data collection and payment handling under an unrelated feature, making social-engineering and privacy harm materially more likely.

Content

No source excerpt is available for this finding.

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
证码后:`python scripts/onboarding.py login <phone> <code>`(workbuddy 宿主加 `--channel workbuddy`)
   - 拿到 `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 LinkFox account onboarding, login, token handling, subscription purchasing, and payment support even though the advertised skill is for Walmart product search/listing. This capability mismatch is a strong indicator of deceptive scope and can trick users or the host into exposing credentials, account access, or payment actions unrelated to the stated function.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill contains SMS login, API-token generation, plan listing, order creation, and payment QR generation features that are not justified by a Walmart search use case. Such hidden capability expansion materially increases the attack surface and enables credential harvesting, unauthorized account linkage, and monetization flows under misleading branding.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares itself as a Walmart product search tool, yet static analysis detected access to environment variables, file writing, and network capabilities without any explicit tool scoping. In an agent setting, undeclared capabilities weaken least-privilege controls and can enable secret access, outbound exfiltration, or local file modification beyond what users would reasonably expect from a search skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest description is primarily written in Chinese while embedding English trigger phrases, but it does not state that users may interact in their preferred language. This can create a language/locale policy issue because the skill presents a fixed language expectation without explicit opt-in or choice.

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

}

text

## curl 示例

```bash
curl -X POST https://tool-gateway.linkfox.com/walmart/search \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Feedback API sends content to a separate external endpoint, and the documentation does not require any user-facing notice or consent before transmitting potentially user-provided text. In an agent skill context, this can cause unintended exfiltration of user prompts, complaints, or other sensitive context to a third party outside the primary tool flow.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The activation logic is broad, relying on generic auth/billing error text and missing-key conditions, which can cause this onboarding behavior to trigger outside a narrowly intended scenario. In a skill with unrelated business purpose, ambiguous activation makes it easier to steer users into unnecessary credential, phone, or payment workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The markdown tells users to provide a phone number for scripted registration but does not present a privacy warning, retention notice, or clear explanation of where the number is sent and how it will be used. This creates a real privacy and trust risk, especially because the request appears inside a Walmart search skill where users would not reasonably expect identity onboarding.

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

The SMS verification flow only accepts 11-digit phone numbers and always uses area code +86, and the CLI help also describes domestic phone numbers only. This enforces a specific locale/language context without any user opt-in or documented justification in this file, which matches the language/locale policy-violation category.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The login flow returns a freshly obtained API key in stdout JSON, which may be captured by logs, calling frameworks, shell history, transcripts, or downstream tools. Exposing long-lived credentials this way increases the risk of credential leakage and unauthorized use, especially because the file is embedded in a skill whose declared purpose does not prepare users for secret-handling behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The login command validates only 11-digit phone numbers and is tied to SMS codes for +86 numbers, which forces a single locale-specific assumption. Because the file does not offer a locale choice or clearly justify the regional restriction, this is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation explicitly says writing to /tmp is forbidden and that failure should occur when the current directory is not writable, but the implementation silently falls back to the home directory and then the temp directory. This mismatch is security-relevant because operators may rely on the documented storage guarantees, while the code can unexpectedly place persistent data in less controlled locations, increasing the chance of disclosure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script persistently stores full Walmart API responses, cache entries, session IDs, and activity metadata on local disk, which goes beyond a simple search/browse function and creates unnecessary data-retention and privacy exposure. If the workspace, home directory, or temp directory is shared or later exfiltrated, product research data, session correlation data, and possibly sensitive API response content become available to unintended parties.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The inline comment for SMALL_THRESHOLD says small responses are output directly and not written to file. In main(), the script serializes the result and writes it to out_path unconditionally before deciding whether to print the full response or only a summary, so the comment contradicts actual behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.