Back to skill

Security audit

Shopify商品查询

Security checks for vulnerabilities and agentic risk

Overview

The skill performs the advertised Shopify product lookup, but it also handles account login, API keys, paid-plan ordering, and persistent local storage in ways users should review carefully before installing.

Install only if you are comfortable giving this skill LinkFox account and billing access, not just Shopify product-search access. Use it with explicit confirmation before login, API-key generation, package purchase, or payment QR creation; avoid running it in environments with untrusted LINKFOX_* variables; do not paste SMS codes or API keys where logs/transcripts are retained; and prefer secure credential storage over shell startup files.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shopify_product_query.py:36
Finding

Credential Exfiltration Through Unrestricted Service Endpoint Overrides

Content
View full analysis
str: """Gateway base URL: LINKFOX_TOOL_GATEWAY takes precedence.""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") 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")) ``` The onboarding utility independently permits all authentication service origins to be replaced: ```python 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" ) ``` Sensitive authentication values are subsequently attached to requests made to these origins: ```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-Ty ...[truncated 2656 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:470
Finding

API Key and SMS Verification Code Exposure Through Process Arguments and Standard Output

Content
View full analysis
dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return {"error": f"login: 手机号格式不正确: {phone}", "phone": masked} if not re.fullmatch(r"\d{4,8}", code): return {"error": f"login: 验证码格式不正确: {code}", "phone": masked} lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} if lg.get("is_new_user"): lbt = _login_by_token(lg["access_token"], lg["refresh_token"]) if "error" in lbt: print(f"{TAG} {lbt['error']}(不影响拿 key)", file=sys.stderr) info = _fetch_user_info_v3(lg["access_token"], lg["user_id"]) if "error" in info: return {"error": info["error"], "phone": masked} tok = _get_or_generate_api_token( lg["access_token"], lg["user_id"], info["group_id"] ) if "error" in tok: return {"error": tok["error"], "phone": masked} return { "api_key": tok["api_key"], "phone": masked, "group_id": info["group_id"], "member_id": info["member_id"], "source": tok["source"], "nick_name": lg.get("nick_name", ""), "team_name": info.get("team_name", ""), "is_new_user": lg.get("is_new_user", False), } ``` The complete object, including the API key, is printed to standard output: ```python def _emit(obj: dict) -> 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.stder ...[truncated 2609 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:160
Finding

Unpinned Runtime Installation of Third-Party Python Packages

Content
View full analysis
dict: try: import qrcode except ImportError: err = "缺少 qrcode 依赖,请运行: 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("缺少 requests 依赖,请运行: pip install requests") ``` ### Technical Analysis When dependencies are missing, the utility instructs the user to install `qrcode`, `pillow`, and `requests` without version constraints, hashes, an audited lock file, an isolated environment, or a controlled package index. Consequently, installation resolves whichever package versions and artifacts are current at execution time. The effective dependency set can therefore change after the Skill itself has been reviewed. A compromised package release, package-index account, dependency tree, or configured package source could introduce arbitrary code. The code does not automatically execute `pip`, which reduces immediate exploitability. Exploitation requires the user or Agent operator to follow the emitted installation instruction. ### Attack Path 1. One of the optional Python dependencies is absent. 2. The onboarding command displays an unpinned `pip install` instruction. 3. The user executes that instruction in the active Python environment. 4. Pip resolves mutable packages and transitive dependencies from the configured index. 5. A compromised or malicious resolved artifact is installed. 6. Malicious package code executes during installation, import, or later use of the onboarding utility. ### Impact Assessment A malicious dependency can execute with the privileges of the user running pip or the onboardin ...[truncated 432 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (18)

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 builds request destinations from environment-controlled base URLs and then sends sensitive login, SMS, token, and user/account data to those endpoints via requests.post. If an attacker can influence environment variables such as LINKFOX_LOGIN_API_URL or LINKFOX_AGENT_USER_API_URL, the skill can be redirected to an attacker-controlled server, causing credential, SMS code, access token, refresh token, and API-key leakage.

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

The gateway request path uses a URL derived from environment variables and sends authenticated requests with the API key in the Authorization header through urllib.request.urlopen. If the environment is attacker-influenced, requests can be redirected to an arbitrary host, exposing the API key and related account/order data and enabling misuse of the victim's account.

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

The request sent via urlopen includes multiple attacker-influenced environment values, and the destination host is also overrideable through LINKFOX_TOOL_GATEWAY. In an agent/runtime context, environment variables are often externally controlled by the orchestrator or calling environment, so this can exfiltrate API credentials and query data to an unintended endpoint or enable SSRF-like outbound connections.

Content

Scanner excerpt · scripts/shopify_product_query.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

The declared purpose is Shopify product filtering, but the detected behavior includes account login, API key generation, account/team info access, subscription browsing, payment order creation, QR code generation, and payment-status queries. This mismatch is dangerous because users may consent to a benign-seeming shopping research skill while it performs credential, billing, and account-management operations that materially expand the trust boundary.

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

This file implements an onboarding and commerce workflow—SMS login, API-key issuance, package listing, ordering, and payment QR generation—which is unrelated to a Shopify product-query skill's declared purpose. That scope mismatch is dangerous because it introduces credential handling and monetization capabilities users would not reasonably expect, increasing the chance of covert data collection or account abuse under the guise of product search.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The billing and payment-order code creates purchasable orders and renders payment QR codes even though the skill is described as a Shopify product query tool. In this context, unexpected payment capabilities materially increase risk of unauthorized charges, social-engineering abuse, and hidden monetization behavior unrelated to the advertised function.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code sends SMS verification codes, performs account login, retrieves user/team metadata, and generates or fetches API tokens, all outside the stated purpose of Shopify product querying. In a mismatched skill context, this is especially risky because it solicits phone numbers and authentication material that can be abused for account takeover, tracking, or unauthorized API access.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill appears to use environment access, file writing, and network capabilities but does not declare any tool scope or permission boundaries. This creates a confused-deputy risk where the agent may invoke more powerful capabilities than users expect, especially in a skill that also references authentication and onboarding flows.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are overly broad, instructing activation whenever users mention related Shopify topics or general product-search intent. In context, this is more dangerous because the skill also appears capable of onboarding, account, and billing actions, so broad triggering increases the chance of unintended invocation and unauthorized side effects.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file documents a separate feedback-submission API that is unrelated to the stated Shopify product-query function of the skill. Mixing an unrelated write-capable endpoint into operational docs increases the chance an agent will call it unexpectedly, enabling unintended outbound data transmission or prompt-influenced exfiltration of user content under the guise of normal skill usage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The onboarding instructions explicitly tell the operator to collect a user's phone number and use it in a registration/login flow, but they provide no privacy notice, consent language, retention limits, or guidance on secure handling of that personal data. In a support workflow, this increases the risk of unnecessary PII collection, accidental disclosure, and non-compliant handling of authentication-related data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file's docstring and command help text are entirely in Chinese, and later user-facing status/error messages are also emitted only in Chinese. For a general-purpose onboarding CLI, this hard-coded locale behavior is a natural-language policy concern because users are not given any option to choose another language or opt in to Chinese output.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
81% confidence
Finding

This code transmits user-supplied and credential-related data to external services during login and account operations. External transmission alone is expected for networked functionality, but in this skill it is more dangerous because the transmitted data includes phone numbers, SMS codes, tokens, and account details unrelated to the declared Shopify query purpose.

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

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module documentation promises that writing to /tmp is forbidden and that an unwritable current directory causes an error, but the implementation silently falls back to the home directory and then the temp directory. This mismatch weakens operator assumptions about where sensitive API output is stored, increasing the chance of data ending up in less protected or shared locations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script persists full API responses to disk and also caches them for 24 hours, regardless of content sensitivity. In an agent skill that queries commercial product data and may include account-scoped results or metadata, unconditional persistence increases exposure through local file access, shared workspaces, backups, or later unintended reuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents use of LINKFOX_AGENT_API_KEY or LINKFOXAGENT_API_KEY for authentication, which involves sensitive credentials. Under the markdown-specific warning rule, the description should explicitly caution users to protect API keys and avoid exposing them in logs, shared shells, or committed files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring that explains usage and behavior is entirely in Chinese, and the script does not offer an alternative language or indicate that the locale is intentionally region-specific. This can violate language/locale policy when users have not opted into Chinese-only behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.