Back to skill

Security audit

EchoTik-商品详情

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches a TikTok product-detail lookup tool, but it adds automatic feedback reporting, credential-heavy onboarding, billing actions, broad script execution, and unsafe storage/network scoping that users should review before installing.

Review this before installing. Use it only if you are comfortable sending TikTok product IDs/URLs and related session metadata to LinkFox, storing full responses on disk, and using LinkFox onboarding/billing flows. Do not provide phone numbers, SMS codes, or payment/order actions unless you explicitly intend to authenticate or purchase credits, and avoid environment-variable endpoint overrides except in a trusted development setup.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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:136
Finding

Automatic Disclosure of User Statements and Intent to an External Feedback Service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/echotik_batch_product_detail.py:36
Finding

Credential-Bearing Requests Can Be Redirected to Environment-Controlled Hosts

Content
View full analysis
str: """Gateway base URL: environment override, otherwise production.""" 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", ) ``` Onboarding accepts additional environment-controlled service origins: ```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", ) ``` Those origins receive access credentials: ```python resp = _http_post( f"{_agent_user_base()}/account/loginByToken", { "token ...[truncated 2319 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/echotik_batch_product_detail.py:251
Finding

Unsanitized Session Identifier Allows Writes Outside the Intended Output Directory

Content
View full analysis
str: """Prefer SESSION_ID; otherwise generate a process-stable identifier.""" 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]: """Return (linkfox_root, session_dir); session_dir always exists.""" 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 implementation has the same issue: ```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 treated as a trusted directory component. It is not restricted to a safe character set and the canonical destination is not checked against the intended LinkFox root. A value containing `../` can traverse out of the date and root directories. On platforms where `sid` is interpreted as an absolute path, `os.path.join()` can discard preceding path components. Subsequent code writes `_meta.json`, API r ...[truncated 1387 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/response_io.py:69
Finding

Generic Response Helper Executes Any Caller-Selected Python File with Inherited Credentials

Content
View full analysis
Path: p = Path(script_arg).expanduser() if not p.is_absolute(): # Resolve relative to the current working directory the agent invoked from. p = (Path.cwd() / p).resolve() else: p = p.resolve() if not p.is_file(): _err(f"--script path not found: {p}") return p ``` The selected file is executed with a copy of the complete environment: ```python def cmd_run(args: argparse.Namespace) -> int: main_script = _resolve_script(args.script) skill_name = _resolve_skill_name(main_script) child_env = os.environ.copy() child_env["PYTHONIOENCODING"] = "utf-8" timed_out = False try: proc = subprocess.run( [sys.executable, str(main_script), args.params], capture_output=True, text=True, encoding="utf-8", errors="replace", env=child_env, timeout=args.timeout, ) ``` The command-line option accepts an arbitrary path: ```python p_run.add_argument( "--script", required=True, help="Path to the main script to execute, e.g. scripts/my_api.py", ) ``` ### Technical Analysis The helper accepts relative or absolute paths and only verifies that the target is a file. It does not ensure that the file belongs to this Skill, is an approved entry point, or has trusted contents. The subprocess inherits the entire parent environment. Consequently, an attacker-controlled Python file can read API keys, session identifiers, workspace variables, and any other environment secrets available to the Skill process. The helper’s declared purpose is response persistence, but arbitrary local program selection is broader than necessary for the product-detail Skill. # ...[truncated 1088 chars]
Remediation
View remediation

other

Warning
Location
scripts/echotik_batch_product_detail.py:61
Finding

Product Requests Transmit Unnecessary Session and Message Metadata

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:482
Finding

Onboarding Prints Full API Keys and Recommends Plaintext Persistence

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} Successfully obtained API key " f"(source: {r['source']})", file=sys.stderr, ) return 0 ``` The onboarding guide recommends shell-profile persistence: ```bash setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc ``` ### Technical Analysis Printing a complete API key to standard output exposes it to terminal scrollback, agent transcripts, command wrappers, CI logs, and any process that captures stdout. The recommended persistence commands place the key in plaintext shell profiles. They may also leave it in shell history. File permissions depend on the user’s existing configuration, and profile files are commonly backed up or synchronized. Although the credential must ultimately be made available to the client, exposing it through user-visible output and shell commands is not the minimum-risk delivery mechanism. ### Attack Path 1. A user com ...[truncated 845 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/echotik_batch_product_detail.py:91
Finding

Complete API Responses Are Duplicated on Disk Without Restrictive Permissions or Cleanup

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (27)

Tainted flow: 'req' from os.environ.get (line 73, 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_batch_product_detail.py (reported line 80)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
94% confidence
Finding

The POST destination is derived from environment-controlled base URLs and then used to send SMS-login data, access tokens, refresh tokens, and API-token requests. In a skill/onboarding context, this creates an exfiltration and SSRF-style risk because a modified environment can silently redirect sensitive authentication traffic to attacker-controlled infrastructure.

Content

Scanner excerpt · scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

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

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The gateway request uses a URL assembled from environment-controlled base configuration and includes the API key in the Authorization header. If the environment is tampered with, requests can be redirected to an attacker server, leaking API credentials and enabling unauthorized actions such as account queries or order operations.

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

A skill advertised as a specialized TikTok product-detail tool should not be able to execute arbitrary local Python via a --script parameter or provide generic file parsing/projection utilities. Arbitrary script execution combined with file persistence and data-extraction features effectively turns the skill into a general-purpose code runner, enabling command execution, data exfiltration, and abuse far beyond its stated business purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill advertised as a specialized TikTok product-detail tool should not be able to execute arbitrary local Python via a --script parameter or provide generic file parsing/projection utilities. Arbitrary script execution combined with file persistence and data-extraction features effectively turns the skill into a general-purpose code runner, enabling command execution, data exfiltration, and abuse far beyond its stated business purpose.

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

}

text

## Display Rules

1. **Present a comparison table**: Show one row per product with key columns — name, price (USD), total sales, 30-day sales, total GMV, rating, review count, commission rate, and number of promoting influencers
2. **Multi-period context**: When comparing momentum, surface the relevant window (e.g. 7d/30d) alongside the cumulative total rather than only the total

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

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The module documentation states that writing to /tmp is forbidden, but the actual implementation falls back to the system temp directory when other locations are not writable. This mismatch is dangerous because operators may rely on the documented guarantee when handling potentially sensitive response data, yet the skill may silently place that data in a less trusted temporary location with broader exposure or weaker lifecycle controls.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements account onboarding, SMS login, API-key acquisition, plan discovery, order placement, and payment QR generation, none of which matches a batch TikTok product-detail lookup skill. That scope mismatch is dangerous because it expands the skill into credential collection and billing workflows users would not reasonably expect from the advertised capability.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Embedding package purchase, order creation, and payment QR rendering in a product-detail lookup skill introduces unjustified financial operations. In this context, the mismatch makes phishing, deceptive upsell, or unauthorized purchase flows more plausible and increases harm beyond normal data retrieval.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code sends SMS verification codes, logs users into LinkFox accounts, and retrieves or generates API keys despite the skill claiming to perform TikTok product-detail queries. This is especially dangerous because it solicits personal phone numbers and authentication factors under a misleading skill identity, enabling credential harvesting or overcollection.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/response_io.py (reported line 223)May include surrounding context.

python
# Force the child process to emit UTF-8 regardless of the host console
    # encoding (Windows defaults to cp936 / gbk and would otherwise corrupt
    # non-ASCII bytes when we read them back).
    child_env = os.environ.copy()
    child_env["PYTHONIOENCODING"] = "utf-8"

    timed_out = False

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares capabilities that imply environment access, file I/O, networking, and shell execution but does not constrain them with an explicit tool scope. In a skill that also references local scripts, persistent storage, and external APIs, this creates avoidable privilege ambiguity and increases the blast radius if the skill is misused or prompt-injected.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger conditions are broad enough to activate on general TikTok product-analysis requests even when the user did not ask for this specific skill or for EchoTik-backed processing. Over-broad activation increases the chance of unintended tool use, unnecessary external data disclosure, and accidental cost-incurring calls in response to ambiguous requests.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to always write full API responses to a session-scoped project directory, which persists user-supplied product lists and returned analytics outside the immediate interaction. Persistent local storage increases the risk of unintended retention, later exposure to other tools/users/processes, and leakage of potentially sensitive commercial research data.

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

}

text

## curl 示例

```bash
curl -X POST https://tool-gateway.linkfox.com/echotik/batchProductDetail \

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation adds a separate feedback-posting API that is outside the skill’s stated purpose of batch TikTok product-detail lookup. In an agent setting, this can create an unexpected secondary action path that sends user-derived content to a different external service, increasing the risk of covert data exfiltration, unauthorized telemetry, or prompt-induced side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The onboarding flow instructs operators to collect a user's phone number and use a script to send SMS codes and log in to an external service, but it does not explicitly disclose that personal data will be transmitted off-platform or require informed consent. In an agent skill context, this creates a privacy and social-engineering risk because users may be prompted to share sensitive contact data without clear notice, data-handling boundaries, or safer alternatives being emphasized first.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill always persists full API responses to disk, including potentially sensitive business data returned from batch product-detail lookups, even though the skill's primary purpose is data retrieval. This expands the data exposure surface by creating local artifacts in predictable locations, which may be accessible to other processes, users, or later sessions depending on the runtime environment.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The inline comment for SMALL_THRESHOLD says small responses are '直接全量输出,不落文件' (printed directly and not saved to file). In main(), the script serializes the response and writes it to out_path unconditionally before deciding whether to print inline or summarize, so the comment contradicts actual behavior.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code enforces an 11-digit phone format and fixed area code '+86', and the entire command help and user-facing text are in Chinese. This imposes a specific locale/language behavior without offering user choice or documenting a justified region-specific constraint in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill generates or fetches API tokens and returns them directly in stdout JSON without any in-file warning, masking, or secure-handling guidance. In agent environments, stdout is often logged, persisted, or exposed to upstream systems, so this can leak long-lived credentials beyond the intended recipient.

Content

No source excerpt is available for this finding.

Unbounded Output

Medium
Category
Output Handling
Confidence
60% confidence
Finding

Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Content

Scanner excerpt · scripts/response_io.py (reported line 175)May include surrounding context.

python
"""Cap the sample's value fields when it has many keys.

    `shape.*.item_keys` is the single source of truth for the full key list
    (always complete, no truncation). The sample only ever shows up to
    SAMPLE_KEY_CAP fields with their concrete values, since the agent only
    needs a feel for value shapes — for the full menu of available fields,
    they read `shape`.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/response_io.py (reported line 228)May include surrounding context.

python
timed_out = False
    try:
        proc = subprocess.run(
            [sys.executable, str(main_script), args.params],
            capture_output=True,
            text=True,