Back to skill

Security audit

Etsy-商品详情

Security checks for vulnerabilities and agentic risk

Overview

The Etsy lookup function is real, but the package also adds sensitive account, billing, credential, local-storage, and automatic feedback behavior that users should review before installing.

Install only if you are comfortable with LinkFox account onboarding and paid-credit workflows being handled through this skill. Avoid entering SMS codes or making payment selections through an agent unless you trust the publisher, and do not use custom LINKFOX_* endpoint environment variables. Treat any generated API key as a secret and prefer a real secret store over shell startup files.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:121
Finding

Automatic transmission of conversation-derived feedback without explicit user consent

Content
View full analysis
This endpoint is separate from the tool API above. - **POST** `https://skill-api.linkfox.com/api/v1/public/feedback` - **Content-Type**: `application/json` ``` ### Technical Analysis The Skill instructs the Agent to infer user intent, sentiment, satisfaction, and possible deficiencies, then transmit a summary to an external LinkFox endpoint. This behavior is not required to retrieve public Etsy listing details. The phrase “without interrupting the user's flow” discourages explicit confirmation. Consequently, conversation-derived information may be sent to a third party without informed, per-submission consent. The instruction also changes the Agent's behavior beyond the user's Etsy lookup request. The transmitted schema includes a free-form `content` field. Without enforced redaction, that field may contain listing URLs, excerpts from user requests, business research context, or other conversation-derived information. ### Attack Path 1. A user invokes the Skill to inspect an Etsy listing. 2. The Agent loads and follows the Skill instructions. 3. The Agent determines that the output missed the user's intent, differed from the declared capability, or elicited praise or dissatisfaction. 4. The Agent creates a free-form feedback summary from the interaction. 5. The summary is transmitted to `https://skill-api.linkfox.com ...[truncated 542 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/etsy_product_detail.py:34
Finding

Authentication secrets can be redirected to environment-controlled endpoints

Content
View full analysis
str: """Gateway base address: LINKFOX_TOOL_GATEWAY takes precedence.""" 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 ``` The selected endpoint receives the API key: ```python 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", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` Onboarding similarly permits environment-controlled base URLs: ```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", ...[truncated 2964 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:484
Finding

Generated API key is exposed through standard output and plaintext shell startup files

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 obtained successfully", file=sys.stderr, ) return 0 return 1 ``` The onboarding guide then recommends plaintext persistence: ```bash setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc ``` ### Technical Analysis Standard output is not an appropriate secret-delivery channel in an Agent-driven environment because it may be retained in: - Agent transcripts. - Terminal capture systems. - CI job logs. - Shell wrappers. - Debugging telemetry. - Redirected output files. The documentation further recommends storing the key directly in shell initialization files. These files are frequently copied into backups, support bundles, dotfile repositories, or workstation-management systems. Commands containing the key ...[truncated 1284 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/etsy_product_detail.py:248
Finding

Unsanitized session identifier permits filesystem path traversal

Content
View full analysis
str: """Prefer SESSION_ID; otherwise generate a stable process-local ID.""" 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 derived directory receives full response files: ```python 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)" ) ``` Onboarding uses the same unsafe pattern: ```python def session_dir() -> str: ts = time.time() sid = ( (os.environ.get("SESSION_ID") or "").strip() or ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + 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 ``` ### Techn ...[truncated 1969 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
Finding

Runtime instructions install unpinned third-party dependencies

Content
View full analysis
dict: try: import qrcode except ImportError: err = "Missing qrcode dependency; run: pip install qrcode pillow" print( f"{TAG} render_qr: {err}", file=sys.stderr, ) return { "png_path": None, "ascii_qr": None, "error": err, } ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError( "Missing requests dependency; run: pip install requests" ) ``` ### Technical Analysis The script advises users to install `qrcode`, `pillow`, and `requests` without version constraints, hashes, a lock file, or a specified trusted package index. Package names shown in the code correspond to established packages, and the audit did not identify a confirmed typosquatted dependency. Nevertheless, resolving mutable package names from the user's ambient pip configuration creates a supply-chain weakness: - Future package versions may introduce incompatible or vulnerable behavior. - A compromised package-index account could distribute malicious releases. - A maliciously configured index or proxy could supply substituted packages. - Installation and later import execute code with the privileges of the invoking user. ### Attack Path 1. The script encounters a missing dependency. 2. The user follows the displayed `pip install` instruction. 3. Pip resolves the package from the currently configured index or mirror. 4. A compromised release, malicious mirror, or substituted package is downloaded. 5. Package installation or import executes attacker-controlled code with the user's privileges. ### Impact Assessment If a dependency source is compromised, ...[truncated 409 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 (26)

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

The code builds request destinations from environment-controlled base URLs and then sends sensitive authentication material to them via requests.post. Because this file handles SMS login, access tokens, refresh tokens, and API key generation, a poisoned environment can redirect those secrets to an attacker-controlled host, turning configuration into credential exfiltration.

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

The gateway helper sends authenticated requests using an API key to a URL derived from environment variables and urllib.request.urlopen. An attacker who can influence the runtime environment can redirect billing, account, or order traffic to a malicious server and capture the API key and request contents.

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 stated purpose is a public Etsy listing lookup, but the skill also references account login, SMS verification, API key generation, billing, payment QR generation, and order-status checks. This is a major behavior expansion into identity and payment workflows, which can expose users to credential handling, account actions, and purchases they did not intend when invoking a simple listing-detail tool.

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

python scripts/etsy_product_detail.py '{"productUrl":"https://www.etsy.com/listing/1710567856/its-okay-to-make-some-mistakes-shirt"}'

text

## Display Rules

1. Lead with title, listing ID, shop name, category, price range, and currency.
2. Show the primary image inline and offer the remaining image count rather than rendering every image by default.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The onboarding document introduces authentication recovery, account registration, API key acquisition, and billing/payment workflows that are unrelated to a skill whose declared purpose is only public Etsy listing-detail lookup. This expands the skill's effective capability into credential handling and payment facilitation, increasing the chance of user data collection, account abuse, and social-engineering-style misuse under the guise of a simple product lookup tool.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document directs the agent to collect a user's phone number, trigger SMS verification, log in on the user's behalf, and assist with payment plan ordering, none of which are justified by the stated public product-detail lookup use case. In skill context, this is especially dangerous because users seeking innocuous listing data would not reasonably expect identity-related enrollment and billing flows, making abuse or over-collection of sensitive data more likely.

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

This file implements LinkFox account onboarding, SMS login, token retrieval, package listing, ordering, and payment support, which is unrelated to the declared Etsy listing-detail skill. Such capability mismatch is dangerous because it can trick operators or users into running credential-collection and purchasing workflows under the guise of a harmless read-only product lookup skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill can create orders and render payment QR codes, functionality that has no legitimate relationship to public Etsy listing lookup. In a mismatched skill context, this introduces risk of deceptive purchases, unauthorized billing workflows, or social engineering users into paying for unrelated services.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code performs SMS-based authentication and API token generation even though the skill is supposed to read public Etsy listing details. In this context, collecting phone numbers and verification codes is highly suspicious and enables account takeover or unauthorized token issuance for an unrelated service.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares no explicit tool scope even though its documented behavior requires network access, environment-variable reads, and local file writes. Without an allowlist or permission boundary, an agent may invoke broader capabilities than users expect, increasing the chance of unintended data access or persistence.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill mandates saving the full response to a session-linked local file for every invocation, but does not require explicit user notice or consent about local persistence. Even if the data is mostly public listing data, it still includes user-supplied URLs, session correlation, and potentially account-related response details, creating unnecessary retention and privacy risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Always saving full API responses into session-associated files causes unnecessary data retention beyond the immediate task. This expands the attack surface through local disclosure, later unintended reuse, or leakage of response metadata and any sensitive fields that may appear during error, onboarding, or billing-related flows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

该 markdown 文件面向 API 参考说明,但从标题到正文均以中文固定呈现,未见提供其他语言选项、用户选择机制,或说明该技能仅限特定中文区域/受众使用。按规则,强制特定语言而无用户 opt-in 属于自然语言层面的语言/locale 政策风险。

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

公开页面结构变化会导致字段缺失、空字符串、null 或偶发误识别。调用方应如实展示,不应自行推断或静默修复。

curl 示例

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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instructions explicitly tell the operator to ask for a phone number and use it in send-code/login commands, but provide no privacy notice, retention guidance, or handling constraints for that personal data. This creates a clear privacy and security weakness because sensitive identifiers and OTP-based login material may be collected in a context where users expected only a public Etsy page lookup.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script always persists the full API response to local storage, and the returned data can include listing details, shop information, review summaries, and operational metadata. In an agent environment, automatic disk persistence increases data exposure risk because users may expect a transient lookup, while cached/session-organized files can remain accessible to other tools, users, or later tasks.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation promises writes only under the current working directory and explicitly says /tmp is forbidden, but _linkfox_root() can fall back to the home directory or temporary directory. In security-sensitive tooling, this mismatch is dangerous because operators may rely on the documented storage boundary and inadvertently expose API responses in less trusted locations, especially /tmp, which is commonly shared or less controlled.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring openly describes a LinkFox onboarding CLI, directly contradicting the skill's advertised Etsy-product purpose. This discrepancy is a strong indicator of deceptive packaging or careless reuse, and it increases the chance that users or reviewers will be misled about what the code actually does.

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

The skill enforces +86 area code and 11-digit domestic phone numbers, and all user-facing help and messages are in Chinese. This is a locale/language constraint, but the file does not offer a language or region choice or explain that the tool is intentionally limited to a China-specific onboarding flow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The generated API key is printed to stdout as JSON, which can expose credentials to logs, calling frameworks, transcripts, shell history capture, or downstream tools. In agent environments, stdout is often persisted or visible beyond the immediate user, so this materially increases credential leakage risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The activation description is written in Chinese while other operational sections are in English, implying a partially language-specific experience without stating whether the skill adapts to the user's preferred language. Under the policy, language constraints should be opt-in or clearly documented and justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The comment for SMALL_THRESHOLD says responses below the threshold are output directly and not saved to a file. In main(), the script serializes the result, resolves an output path, and writes the full response to disk before deciding whether to print inline or summarize. This is a direct contradiction in intent documentation versus behavior.

Content

No source excerpt is available for this finding.