Back to skill

Security audit

EchoTik-TikTok店铺搜索

Security checks for vulnerabilities and agentic risk

Overview

This seller analytics skill has real seller-search functionality, but it also adds silent feedback reporting plus credential, account, and payment flows that need careful review before installation.

Install only if you are comfortable with LinkFox receiving your seller-search queries and potentially feedback content, and avoid using the phone-login/payment flows unless you explicitly intend to. Prefer getting and storing API keys through a secure external process, verify LINKFOX_* endpoint environment variables are not overridden, and treat saved linkfox response/cache files as potentially sensitive business data.

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

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:219
Finding

Silent disclosure of user statements and inferred intent through the Feedback API

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:72
Finding

Environment-controlled API origins allow credential redirection

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") ``` Authentication headers are attached without validating the selected origin: ```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 ``` The login flow sends access and refresh tokens to the configurable Agent User origin: ```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", ...[truncated 3095 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/echotik_list_seller.py:36
Finding

Seller-search API key and Agent metadata can be sent to an arbitrary gateway

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(): key = os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get("LINKFOXAGENT_API_KEY") if not key: print( "API Key not configured. Please complete authorization first:\n" "1. Visit https://skill.linkfox.com/linkfoxskills/guide.htm to obtain your Key\n" "2. Set the environment variable: export LINKFOX_AGENT_API_KEY=your-key-here", 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", ""), "MESSAGE_ID": os.environ.get("MESSAGE_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", ) ``` ### Technical Analysis `LINKFOX_TOOL_GATEWAY` fully controls the request origin. The code appends the fixed API path but does not verify that the resulting URL uses HTTPS or belongs to an approved LinkFox hostname. The API key is then attached to the request as an `Authorization` header. In addition to the seller-search ...[truncated 1196 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:484
Finding

Generated API keys are exposed through standard output and persistent plaintext configuration

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 return 1 ``` The onboarding documentation recommends persistent plaintext storage: ```markdown - Windows PowerShell: `setx LINKFOX_AGENT_API_KEY ""` - macOS zsh: `echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc` - Linux bash: `echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc` ``` ### Technical Analysis The login command serializes the complete API key into stdout. Standard output is commonly captured by Agent transcripts, terminal logging, CI logs, shell wrappers, process supervisors, and command-substitution pipelines. This makes a long-lived credential visible outside the minimum credential-handling boundary. The documentation further recommends writing the key into shell initialization files. These files are plaintext and may be readable by backup software, endpoint-management tools, support utilities, accidental repository commits, or other processes running as the user. They also expose the key to ev ...[truncated 1055 chars]
Remediation
View remediation

other

Warning
Location
scripts/echotik_list_seller.py:59
Finding

Unnecessary Agent session and message identifiers are transmitted with seller queries

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/echotik_list_seller.py:248
Finding

Unvalidated SESSION_ID permits output path traversal

Content
View full analysis
str: """优先 env SESSION_ID;缺省按 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"] def _ensure_session(ts: float) -> tuple[str, str]: """返回 (linkfox_root, session_dir);session_dir 一定存在。""" 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 ``` The resulting session directory is used to save complete API responses: ```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 ``` ### Technical Analysis `SESSION_ID` is treated as a trusted filesystem component. No validation rejects absolute paths, `..` traversal components, directory separators, or platform-specific path forms. `os.path.join` does not guarantee confinement: an absolute final component can discard preceding components, while traversal segments can resolve outside the intended session root. The code creates the selected directory and writes `_meta.json` plus complete seller-search response files beneath it. A malicious parent process or launche ...[truncated 1486 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:172
Finding

Credential-handling onboarding flow recommends unpinned runtime dependencies

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 The onboarding script recommends installing `qrcode`, `pillow`, and `requests` without version constraints, hashes, a lockfile, or a specified trusted index. The effective code installed by these commands can change after the Skill has been audited. These packages are imported into a process that handles phone numbers, SMS codes, access tokens, refresh tokens, API keys, account identifiers, and payment QR content. A compromised package release, package-index compromise, or unexpected future version could execute code with access to those values and the user's local privileges. No evidence shows that the named packages are currently malicious. The vulnerability is the absence of dependency integrity and reproducibility controls in a security-sensitive flow. ### Attack Path 1. The user invokes onboarding on a system lacking one of the optional dependencies. 2. The script instructs the user to run an unpinned `pip install` command. 3. The package installer retrieves whichever version the configured package index currently serves. 4. A compromised or incompatible package executes during installation or import. 5. The package runs with the user's privileges and can access onboarding inputs, environment credentials, local files, and network resources. ### Impact Assessment A malicious depe ...[truncated 369 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 (28)

Tainted flow: 'req' from os.environ.get (line 71, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request sent via urlopen includes environment-derived values in both the destination base URL and multiple HTTP headers. If an attacker can influence LINKFOX_TOOL_GATEWAY or session-related environment variables, the skill can exfiltrate API keys and user/session metadata to an attacker-controlled endpoint, creating an SSRF-style data leak channel. The skill context makes this more dangerous because it handles authenticated seller-search requests and automatically attaches authorization and session identifiers.

Content

Scanner excerpt · scripts/echotik_list_seller.py (reported line 78)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 ""

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

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The code builds request destinations from environment variables and then sends login, token, and account data to those URLs with no allowlist, scheme validation, or certificate pinning. In a skill/runtime context where environment variables may be influenced by deployment or a malicious wrapper, this can redirect sensitive authentication traffic to an attacker-controlled endpoint and exfiltrate SMS login credentials, access tokens, and generated 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
91% confidence
Finding

The gateway request path uses environment-derived base URLs and includes the API key in the Authorization header for outbound requests. If an attacker can alter the environment, they can redirect billing/account queries and order operations to an external host and capture the API key or manipulate responses, turning this into credential exfiltration and possible financial abuse.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a seller analytics/search tool, but the findings indicate it also supports phone-based login, token generation, account/team inspection, package listing, payment order creation, QR code generation, and payment-status checks. That mismatch is dangerous because it hides identity, billing, and account-management actions behind an analytics facade, undermining user consent and enabling unexpected sensitive operations.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger criteria are intentionally broad enough to activate even when the user does not explicitly mention TikTok or EchoTik. Overbroad triggering can cause the agent to route unrelated shopping, store-search, or competitor-analysis requests into this skill, leading to unintended external calls, cost incurrence, and exposure of user context to a third-party service.

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

}

text

## Display Rules

1. **Present data clearly**: Show results in a table with key columns — store name, region, total sales, 30-day GMV, followers, rating, review count, and number of promoting influencers
2. **GMV & sales granularity**: When relevant, show 30-day GMV and total sales; mention multi-period breakdowns (1d/7d/30d/90d) are available in the saved JSON

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill documents a flow where the operator can collect a user's phone number, send a code, and log in via a script to obtain an API key. That capability is unjustified for a seller-analytics skill and exposes users to credential interception, account takeover risk, and improper handling of personal data and one-time codes.

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
示 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

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file implements account onboarding, SMS authentication, API-key issuance, and purchasing flows that materially exceed the declared seller-analytics skill scope. In an agent ecosystem, such scope drift is dangerous because users invoking a data-analysis skill may be unexpectedly prompted into identity, credential, or payment actions, increasing the chance of deceptive collection of secrets and financial operations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code creates orders and renders payment QR codes even though the skill is described as seller analytics. That mismatch raises phishing and unauthorized-purchase risk because a user or calling agent may not expect a data-analysis tool to initiate billing or generate payment artifacts.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool scope while its documented behavior uses environment variables, network access, and file writes. Without least-privilege scoping, an agent may invoke capabilities beyond what users reasonably expect, increasing the blast radius if the skill is abused or mis-triggered.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

Defaulting to the US marketplace when the user does not specify a region can cause silent parameter injection that changes the meaning of the user's request. In a paid live-query workflow, this may lead to unnecessary billable calls, inaccurate results, and unintended disclosure of user intent to an external API without explicit user choice.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill requires every full API response to be written to a session-linked path under the current project directory. Persistent storage of full responses can retain sensitive business queries, account metadata, identifiers, and result data longer than necessary, making them accessible to other tools, users, or later tasks in the same workspace.

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

}

text

## curl 示例

### 基础店铺列表(按总销售额降序)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file documents a separate feedback API that is unrelated to the seller-search function of this skill. In an agent setting, this creates an unnecessary data egress path that could be invoked with user content or session-derived information, expanding the skill's effective scope beyond the declared purpose and enabling unauthorized transmission to a third-party endpoint.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The onboarding document expands the skill from seller-search analytics into account recovery, registration, and payment workflows that are not part of the declared purpose. This broadens the trust boundary and creates unnecessary opportunities to collect sensitive data, steer users into purchases, and invoke privileged scripts unrelated to the core analytics function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instructions involve handling phone numbers and login codes but provide no privacy, retention, masking, or consent guidance. In practice, this can lead to unnecessary collection of sensitive personal data and insecure transmission or storage of authentication factors.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document tells users to persist API keys in shell startup files without warning that these files may be readable by other local processes, exposed through backups, or accidentally disclosed during support/debugging. Long-lived environment persistence also increases the blast radius if the host is compromised.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documented billing flow allows the skill to list plans, create payment orders, and guide users through payment methods, which is outside the seller-search function. Embedding commerce and payment assistance inside an analytics skill increases phishing, social-engineering, and unauthorized purchase risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The natural-language description and usage/output policy are written entirely in Chinese, which imposes a specific language context without offering a choice or documenting that the skill is region- or language-specific. Under the stated policy, locale constraints should be opt-in or clearly justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring explicitly promises that writing to /tmp is forbidden, but the implementation falls back to tempfile.gettempdir(), which commonly resolves to /tmp. This mismatch can cause sensitive API responses to be written to a less controlled shared temporary location contrary to operator expectations, increasing risk of unintended disclosure on multi-user systems or ephemeral runners.

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

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill performs SMS-based login and then returns a usable API key, which is a credential bootstrap capability outside the advertised analytics scope. In context, that makes the skill more dangerous because it can collect authentication factors and mint reusable secrets under the cover of a benign-seeming seller-analysis feature.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language behavior and validation logic require an 11-digit domestic mobile number and force the area code to +86, which imposes a specific locale/language-region constraint. Because the file does not offer user opt-in or document this as a justified region-specific limitation, it fits the locale policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The login request payload fixes the areaCode to +86 for all users, making the skill's authentication flow region-locked by default. This is a natural-language locale policy concern because the tool enforces a specific locale without offering an explicit user choice or stating a justified regional scope.

Content

No source excerpt is available for this finding.