Back to skill

Security audit

Sorftime-Walmart类目市场研究

Security checks for vulnerabilities and agentic risk

Overview

The skill is a Walmart category research tool, but it also handles login, API keys, billing/payment, and silent feedback reporting in ways users should review carefully before installing.

Install only if you are comfortable giving this skill LinkFox API credentials and using its account, billing, and payment helper flows. Avoid entering phone verification codes or creating payment orders through the agent unless you explicitly intend to, review any feedback payload before it is sent, and store API keys in a proper secret manager rather than shell profiles or logs.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:71
Finding

Credential-Bearing Requests Can Be Redirected to Attacker-Controlled Endpoints

Content
View full analysis
str: for n in (name, *fallbacks): v = os.environ.get(n) if v: return v.rstrip("/") return default.rstrip("/") 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_host}", "Referer": f"https://{origin_host}/", "source": source, "User-Agent": UA, } if access_token: h["authorization"] = access_token h["uid"] = _uid_header(access_token, user_id) if user_id else _LOGIN_FIXED_UID if group_id: h["tid"] = group_id return h ``` ```python def _gateway(method: str, path: str, body: dict | None = None) -> dict: url = f"{_agent_base()}{path}" body_bytes = json.dumps(body or {}).encode() if method == "POST" else None last_exc: Exception = RuntimeError("Unknown error") for attempt in range(3): if attempt: time.sleep(1 << (attempt - 1)) headers = {"Authorization": _api_key()} if method == "POST": headers["Con ...[truncated 3858 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:484
Finding

Generated API Key Is Printed in Plaintext and Recommended for Plaintext Shell-Profile Storage

Content
View full analysis
None: print(json.dumps(obj, ensure_ascii=False, indent=2)) ``` The onboarding documentation then recommends commands equivalent to: ```bash setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc ``` ### Technical Analysis `login_and_get_key` returns the complete generated API key in a dictionary, and `_emit` serializes that dictionary directly to stdout. Agent hosts, terminal recorders, CI systems, process wrappers, and support tooling commonly retain stdout. As a result, a long-lived credential may enter transcripts or logs outside the user's intended secret-storage boundary. The onboarding guide compounds the problem by recommending insertion of the plaintext key into shell startup files. Such files may be readable by backup agents, diagnostic tools, editor extensions, or other processes running as the same user. Directly embedding the key in a command can also expose it through terminal history or command logging. ### Attack Path 1. A user runs `python scripts/onboarding.py login `. 2. The service returns or generates an API key. 3. `_emit` writes the complete key to stdout. 4. The hosting Agent, CI job, t ...[truncated 714 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:92
Finding

Skill Instructs the Agent to Submit Conversation-Derived Feedback Without Explicit Consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/sorftime_walmart_category_market.py:254
Finding

Unsanitized SESSION_ID Enables Filesystem Path Escape

Content
View full analysis
str: """Prefer 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"] ``` ```python def _ensure_session(ts: float) -> tuple[str, str]: 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 ``` ```python def resolve_data_path(slug: str, ts: float, ext: str = "json") -> str: _, session_dir = _ensure_session(ts) sub = os.path.join(session_dir, "data") os.makedirs(sub, exist_ok=True) out = os.path.join( sub, f"{slug}-{int(ts * 1_000_000)}.{ext}", ) _update_meta( session_dir, skill=slug, kind="data", file_rel=os.path.relpath(out, session_dir), ts=ts, ) return out ``` ```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", encoding="utf-8") as f: f.write(serialized) ``` The onboarding script uses the same unsafe pattern: ```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)) + "-" + s ...[truncated 1778 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:162
Finding

Runtime Guidance Installs Unpinned Third-Party Dependencies

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 script recommends installing `qrcode`, `pillow`, and `requests` without version constraints, lockfiles, or package hashes. This makes the installed code dependent on whatever versions the package index resolves at execution time. The referenced package names are established packages, and the audit found no evidence that the Skill intentionally references a malicious package. The risk arises from non-reproducible dependency resolution, future package compromise, incompatible releases, or use of a malicious package index configured in the local environment. ### Attack Path 1. The user runs onboarding in an environment missing one of the optional dependencies. 2. The script tells the user to execute an unrestricted `pip install` command. 3. The local Python configuration resolves packages from its configured index without a reviewed lockfile or required hashes. 4. A compromised index, dependency, account, or future release supplies malicious installation or import-time code. 5. The package executes with the privileges of the user running the installation or Skill. ### Impact Assessment A compromised dependency could execute arbitrary Python code with the current user's ...[truncated 233 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (24)

Tainted flow: 'url' from os.environ.get (line 235, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The script builds destination base URLs from environment variables and then sends login data, SMS verification requests, bearer tokens, and token-generation requests to those endpoints via requests.post. If an attacker can influence the environment, they can redirect these highly sensitive flows to attacker-controlled infrastructure and capture credentials or API keys.

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

The gateway request path uses a URL derived from environment-controlled base configuration and attaches the API key in the Authorization header before calling urlopen. A manipulated environment can exfiltrate the user's API key and any billing/order traffic to an attacker-controlled endpoint.

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request destination is influenced by the environment via LINKFOX_TOOL_GATEWAY and then used by urlopen with the Authorization API key attached. In an agent/runtime context, environment variables are often externally controlled, so this enables SSRF-style outbound requests and can exfiltrate the API key and request data to an attacker-controlled host.

Content

Scanner excerpt · scripts/sorftime_walmart_category_market.py (reported line 84)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=120) 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 manifest presents the skill as a Walmart category research utility, but the broader referenced behavior includes account login, API key generation, team/user info access, package listing, order creation, payment QR generation, and payment-status queries. That is a substantial expansion of scope into identity, billing, and account operations, which can mislead users and cause collection or use of highly sensitive data under false pretenses.

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

md
Prefer `searchByName` when the user supplies a natural-language category name. Use `tree` only when full hierarchy traversal is required. A tree response can be approximately 10 MB; normally inspect its saved JSON selectively rather than using `--inline`.

## Display Rules

1. State the selected operation and show `requestConsumed` and `costToken` when returned.
2. For `tree`, show matched category names, their ID hierarchy, and the derived `nodePath`; never dump the full tree into conversation.

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

This skill is advertised as Walmart category research, but the file implements account onboarding, SMS login, API key issuance, package listing, order creation, and payment QR generation. That scope mismatch is dangerous because users invoking a benign research skill could be induced into credential entry and billing flows they did not expect.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file can create purchase orders and render payment QR codes even though the skill's stated purpose is market/category analysis. In this context, hidden billing capability materially increases abuse risk because a user may be steered into unauthorized purchases under the guise of research tooling.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script performs SMS-based authentication, obtains access tokens, queries team/user info, and generates or retrieves API tokens, which exceeds the declared Walmart research scope. In context, this creates a high-risk credential-harvesting and privilege-delegation surface disguised as a content-research skill.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documentation indicates access to environment variables, network calls, and file writes, but it does not declare any explicit tool scope or permission boundaries. This weakens reviewability and least-privilege guarantees, making it easier for the skill to access sensitive data or perform side effects beyond what a user would reasonably expect from a category-research tool.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instruction to automatically report feedback, dissatisfaction, or intent/result mismatches to a separate Feedback API introduces secondary data sharing unrelated to the core category-research task. This creates an undisclosed telemetry channel that may transmit user behavior or conversation-derived signals to another service without clear necessity or consent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Automatic submission of user feedback and mismatch signals is not justified by the stated purpose of Walmart category research, so it expands data processing beyond user expectations. Even if the payload seems operational, it can reveal preferences, dissatisfaction, usage patterns, or fragments of task context to an external endpoint.

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

| 5112 | 其他上游业务异常 | 保留返回信息并反馈 | | 5901 | 服务内部错误 | 稍后重试或反馈 |

curl 示例

bash
API_KEY="${LINKFOX_AGENT_API_KEY:-$LINKFOXAGENT_API_KEY}"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation adds a feedback-submission API that is unrelated to the Walmart category research capability, expanding the skill's effective scope from read-only research into outbound user-content transmission to a separate external service. This creates an unnecessary data-exfiltration path and increases the chance that user prompts, results, or identifiers are sent off-platform without clear need or consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The feedback endpoint invites arbitrary free-form content submission to an external domain but provides no privacy or data-handling warning. In an agent setting, this omission is dangerous because users or integrators may include sensitive prompts, business data, API outputs, or identifiers in the feedback body, causing unintended disclosure to a third party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The onboarding instructions explicitly tell the operator to collect a user's phone number and use it to trigger registration/login flows, but provide no privacy notice, consent language, data minimization guidance, retention limits, or safe handling requirements. This creates a real privacy and account-security risk because the workflow handles personal data and authentication factors in a manual support context, increasing the chance of misuse, leakage, or unauthorized account creation/access.

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 = ""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script retrieves or generates an API key and emits it in stdout JSON without any in-file warning or masking guidance. In agent environments, stdout is often logged, stored, or exposed to parent processes, so this can lead to accidental credential leakage and downstream account compromise.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The top-level docstring states that the full response is always written to <cwd>/linkfox/... and that writing to /tmp is prohibited if the current directory is not writable. However, _linkfox_root() explicitly falls back to ~/linkfox and then $TMPDIR/linkfox when earlier candidates are not writable, and _resolve_output_path() uses that fallback logic. This is a direct mismatch between the documented storage behavior and the implemented behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The inline documentation says output is always written under the current working directory and explicitly forbids /tmp. In contrast, _linkfox_root() is documented and implemented to auto-fallback to alternate locations, including the temp directory, when the preferred directory is read-only. This is an active contradiction between documentation and behavior, not merely omitted detail.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The primary description is written in Chinese while other user-facing sections are in English, but the file does not state a language preference policy or offer the user a choice of language. This can create a locale/language policy issue if the skill is invoked for users who did not opt into Chinese output or mixed-language instructions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file specifies that all operations target Walmart US, which is a locale constraint, but it does not present this as a user-selectable option or require confirmation that the user wants US-market data. Under the language/locale policy, forcing a locale without opt-in can be a natural-language policy concern unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The QR rendering function creates a PNG file under a session directory on the local filesystem. While the order subcommand name mentions rendering a payment QR code, this file does not clearly warn users that a persistent image file will be created and where it will be stored.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

_resolve_output_path() says it resolves to <cwd>/linkfox/<日期>/<session>/data/..., but it calls resolve_data_path(), which ultimately uses _linkfox_root(). _linkfox_root() can select ACPX workspace, home-directory, or temp-directory roots instead of the current working directory. The function-level documentation therefore misstates the actual behavior.

Content

No source excerpt is available for this finding.