Back to skill

Security audit

EchoTik-TikTok店铺商品列表

Security checks for vulnerabilities and agentic risk

Overview

This skill can retrieve TikTok seller products, but it also adds account login, API-key, payment, persistent storage, and automatic feedback-reporting behavior that needs careful review.

Install only if you are comfortable giving LinkFox API access, saving full seller-query responses locally, and using this skill for account and billing recovery. Avoid entering SMS codes or creating payment orders through the agent unless you intentionally trust the LinkFox service, and prefer manual API-key setup outside chat/log-visible contexts.

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:163
Finding

Automatic External Reporting of User Statements and Intent Without Consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/echotik_list_seller_product.py:36
Finding

Credential-Bearing Requests Can Be Redirected to Arbitrary Endpoints

Content
View full analysis
str: 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 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") with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` Onboarding exposes additional configurable destinations: ```python 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", ) ``` Access and refresh tokens are subsequently sent to the configured endpoint: ```python resp = _http_post( f"{_agent_user_base()}/account/loginByToken", { "token": access_token, "refreshToken": refresh_token, "device": { "aid": "3026344186", "did": "", "type": "Windows", "os": "10", ...[truncated 1547 chars]
Remediation
View remediation

other

Warning
Location
scripts/echotik_list_seller_product.py:58
Finding

Unnecessary Agent Session Metadata Is Transmitted With Product Queries

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:470
Finding

Generated API Key Is Exposed Through Standard Output and Agent Context

Content
View full analysis
dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return {"error": f"login: invalid phone format: {phone}", "phone": masked} if not re.fullmatch(r"\d{4,8}", code): return {"error": f"login: invalid verification code format: {code}", "phone": masked} lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} 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), } 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 obtained successfully", file=sys.stderr) return 0 return 1 ``` The onboarding instructions then direct the Agent to relay shell commands containing the key: ```markdown setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc ``` ### ...[truncated 1174 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:162
Finding

Unpinned Runtime Dependency Installation Guidance Creates Supply-Chain Risk

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, } def _require_requests() -> None: if requests is None: raise RuntimeError( "Missing requests dependency; run: pip install requests" ) ``` ### Technical Analysis The runtime messages direct users to install mutable package names without exact versions, cryptographic hashes, a lock file, or a specified trusted package index. Python package installation may execute package build and installation logic with the privileges of the invoking user. A compromised package release, unsafe package index, dependency confusion condition, or future incompatible version could therefore introduce arbitrary code or unstable behavior. ### Attack Path 1. Onboarding encounters a missing `qrcode`, `pillow`, or `requests` dependency. 2. The user follows the displayed `pip install` command. 3. pip resolves the package and transitive dependencies from the configured index. 4. Package build or installation code runs locally. 5. A compromised or substituted package executes with the user's privileges. ### Impact Assessment A malicious dependency can access files and environment variables available to the Python process, including API keys and Agent session data. It can also modify user files, establish persistence, or perform arbitrary network operations within the user's privilege boundary. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/echotik_list_seller_product.py:248
Finding

Unsanitized Session Identifier Permits Filesystem Path Escape

Content
View full analysis
str: 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]: 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 onboarding script repeats the same 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)) + "-" + secrets.token_hex(3) ) path = os.path.join( _linkfox_root(), time.strftime("%Y-%m-%d", time.localtime(ts)), sid, ) os.makedirs(path, exist_ok=True) return path ``` ### Technical Analysis `SESSION_ID` is used as a path component without rejecting: - Absolute paths. - `..` traversal components. - Directory separators. - Platform-specific path prefixes. If `sid` is absolute, `os.path.join` can discard the preceding root components. Traversal components can likewise escape the expected date directory. Subsequent functions write metadata, complete API responses, or QR images beneath the resulting path. Exploitation requires control of the process environment or a launcher that propagates an attacker-controlled session value. ## ...[truncated 796 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/echotik_list_seller_product.py:204
Finding

Complete Responses and Payment Artifacts Can Fall Back to Shared Temporary Storage

Content
View full analysis
str: cached = _SESSION_CACHE.get("_root") if cached: return cached candidates = [] acpx = (os.environ.get("ACPX_WORKSPACES") or "").strip() if acpx: acpx = acpx.split(os.pathsep)[0].strip() if acpx: candidates.append(os.path.join(acpx, "linkfox")) candidates.append(os.path.join(os.getcwd(), "linkfox")) candidates.append(os.path.join(os.path.expanduser("~"), "linkfox")) import tempfile candidates.append( os.path.join(tempfile.gettempdir(), "linkfox") ) for root in candidates: try: os.makedirs(root, exist_ok=True) probe = os.path.join(root, ".write_probe") with open(probe, "w", encoding="utf-8") as f: f.write("") os.remove(probe) except OSError: continue root = os.path.abspath(root) _SESSION_CACHE["_root"] = root return root ``` Complete responses are then written using ordinary file creation: ```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} " f"({len(serialized)} bytes)" ) except OSError as e: print( f"Failed to save to {out_path}: {e}", file=sys.stderr, ) ``` The onboarding script has an equivalent temporary-directory fallback for payment QR images: ```python candidates += [ os.path.join(os.getcwd(), "linkfox"), os.path.join(os.path.expanduser("~"), "linkfox"), os.path.join(tempfile.gettempdir(), "linkfox"), ] ...[truncated 1283 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
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/echotik_list_seller_product.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
95% confidence
Finding

The POST target URL is derived from environment-controlled base URLs and then used to send login data, SMS codes, access tokens, refresh tokens, and API-token requests. In an agent/skill environment, this creates an SSRF-style exfiltration path where a modified environment can redirect sensitive authentication traffic to an attacker-controlled host.

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 URL is also assembled from environment-controlled base configuration and used with an Authorization header carrying the API key. If an attacker can influence environment variables, requests can be redirected to an arbitrary endpoint and the API key disclosed, while also enabling unauthorized outbound access from the agent runtime.

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 documented purpose is a seller product listing tool, but the behavior reportedly includes SMS login, token generation, user/team info retrieval, subscription/package listing, payment order creation, QR-code generation, and payment-status polling. That is a major capability expansion into authentication, account management, and payments, which can expose credentials, enable unauthorized account actions, or charge users under the guise of analytics.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The trigger conditions are intentionally broad and state the skill should activate even when the user does not explicitly mention EchoTik or TikTok. Over-broad triggering can cause the wrong skill to run, leading to unintended external calls, unnecessary cost consumption, and disclosure of user queries to third-party services outside the user's expectation.

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

}

text

## Display Rules

1. **Present data clearly**: Show products in a table with key columns — product image, title, price, total sales, 30-day sales/GMV, rating, review count, and commission rate
2. **Sales & GMV granularity**: When relevant, show total sales and total GMV; mention multi-period breakdowns (1d/7d/15d/30d/60d/90d) are available in the saved JSON

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The onboarding document adds authentication recovery, account registration, and billing/payment workflows that are outside the stated purpose of a seller-product analytics skill. This expands the skill's effective scope into credential handling and monetization, creating an unnecessary pathway for collecting secrets and directing users into sensitive flows unrelated to product lookup.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation instructs the agent to collect a phone number, send an SMS code, log in, list plans, and create payment orders, none of which are justified by the skill's analytics function. Embedding account creation and purchase capabilities in a data-query skill increases the risk of unauthorized account actions, phishing-like behavior, and abuse of user trust.

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

The file implements LinkFox account onboarding, SMS login, plan purchase, order management, and payment QR rendering, which is materially unrelated to the declared TikTok seller-product listing skill. This functionality mismatch is dangerous because it can trick users or the platform into executing credential collection and monetization flows under false pretenses.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Adding account login, plan listing, order creation, and payment QR generation to a product-analytics skill introduces unjustified financial and authentication operations. In this context, such hidden capabilities increase the risk of credential harvesting, unauthorized purchases, and deceptive user flows far beyond the stated feature set.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code performs SMS-based login and retrieves or generates LinkFox API tokens, despite the skill claiming to list TikTok seller products. This is highly dangerous because it acquires reusable credentials that can enable continued access to the user's account or workspace, and the deceptive mismatch strongly elevates suspicion of credential theft or unauthorized account takeover support.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill declares no explicit tool scope or permission boundaries despite documenting capabilities that use environment variables, network access, and file writes. Without least-privilege constraints, an agent may invoke broader capabilities than users expect, increasing the blast radius if the skill is misused or its instructions are subverted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation says full API responses are always written to local files, but it does not provide a clear privacy warning or obtain consent for persistence. Even if the data seems business-oriented, saved responses can contain identifiers, session-linked metadata, and commercially sensitive analytics that remain on disk beyond the immediate interaction.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Always writing complete API responses into session-organized files under the current project directory creates persistent local copies of potentially sensitive user-linked data. In shared workspaces, repos, synced folders, or later debugging/log collection, those files may be exposed to other users, tools, or accidental commit/upload.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file directs the agent to use references/onboarding.md to guide users through authentication and billing issues, and the surrounding section is written only in Chinese with no indication that users may choose another language. This can violate a language/locale choice policy when interacting with users who have not opted into Chinese.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Automatically sending feedback via an external API is unrelated to the core product-listing function and may transmit user content, task context, or behavioral telemetry without meaningful consent. Because it is framed as non-interrupting, users may not realize extra outbound data sharing is occurring.

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

}

text

## curl 示例

### 基础店铺商品列表(按总销量降序)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file documents a separate feedback-reporting endpoint that is unrelated to the seller-product listing function of this skill. This expands the skill's effective scope and creates a path for transmitting user-derived content to an external service, which can be abused for unauthorized data exfiltration or hidden side effects if an agent implements it automatically.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The feedback endpoint encourages sending free-form content externally but provides no privacy guidance, data-minimization rules, or warning against including sensitive user data. In an agent setting, this omission can lead to inadvertent disclosure of user prompts, identifiers, or internal context to a third-party endpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill tells the agent to ask for a user's phone number and process SMS-based login without any user-facing privacy warning, consent language, or data-handling notice. This can lead users to share personal data and one-time codes in a conversational context without understanding who receives the data, how it is used, or the risks of account compromise.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill writes full API responses and session metadata to local files even though its stated purpose is only to query seller product data. Persisting complete responses can expose potentially sensitive business data, session identifiers, and usage metadata to other local users, future tasks, or unintended tooling, increasing data-retention and confidentiality risk.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documentation promises not to write to /tmp and to fail if the current directory is not writable, but the implementation silently falls back to home or temporary directories. This mismatch is dangerous because operators may rely on the documented storage boundary, while the code actually persists data in broader or less controlled locations, increasing accidental disclosure risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The order flow writes payment QR code images to disk in a session directory without an explicit warning in the code path. While not as severe as credential theft, this can leave payment artifacts on shared systems or workspaces where other users or processes may access them.

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