Back to skill

Security audit

大麦数据美客多市场洞察与选品

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a Mercado Libre research tool, but it also includes sensitive account onboarding, payment-order creation, public image upload, automatic feedback reporting, and broad local response retention that users should review carefully.

Install only if you trust LinkFox with market queries, local images you choose for image search, and account/billing workflows. Prefer obtaining and storing API keys outside the agent in a secure credential manager, avoid giving SMS codes unless you intentionally want assisted onboarding, confirm any paid calls or payment orders yourself, and treat uploaded images as publicly accessible during the stated availability window.

Vulnerability Patterns
  • 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
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/damai_mercado_market_intelligence.py:36
Finding

Credentials and personal data can be transmitted to environment-controlled endpoints

Content
View full analysis
str: """Gateway base address: environment variable first, production fallback.""" return ( os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com" ).rstrip("/") ``` ```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") with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` The onboarding client separately permits authentication endpoints to be replaced: ```python def _agent_base() -> str: return _env_base( "LINKFOX_AGENT_API_URL", "https://tool-gateway.linkfox.com", "LINKFOX_TOOL_GATEWAY", ) def _login_base() -> str: return _env_base("LINKFOX_LOGIN_API_URL", "https://api.linkfox.com") def _agent_user_base() -> str: return _env_base( "LINKFOX_AGENT_USER_API_URL", "https://agent-api.linkfox.com", ) ``` ### Technical Analysis The code treats environment variables as trusted network destinations and attaches sensitive authentication material without validating the resulting scheme or host. Depending on the operation, transmitted data can include: - LinkFox API keys - Acc ...[truncated 1669 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:468
Finding

Generated API keys are printed to stdout and users are directed to persist them in plaintext

Content
View full analysis
dict: masked = _mask_phone(phone) # Authentication and token-generation steps omitted here. 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), } ``` ```python def _emit(obj: dict) -> None: print(json.dumps(obj, ensure_ascii=False, indent=2)) def _cmd_login(args) -> int: r = login_and_get_key(args.phone.strip(), args.code.strip(), args.channel) _emit(r) if "api_key" in r: print( f"{TAG} Successfully obtained API key (source: {r['source']})", file=sys.stderr, ) return 0 return 1 ``` The onboarding instructions direct users to save that key persistently: ```text 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 The login command serializes the complete API key to stdout. In an Agent environment, stdout may be captured in model context, conversation transcripts, terminal logs, shell pipelines, CI logs, debugging output, or monitoring systems. The documentation then instructs users to place the complete secret directly in shell startup files. These files ar ...[truncated 1269 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/upload_image.py:90
Finding

Local images are uploaded with public-read access without sufficient disclosure safeguards

Content
View full analysis
str: """Extract the base public URL by stripping query parameters.""" return presigned_url.split("?")[0] ``` ```python public_url = extract_public_url(presigned_url) print(json.dumps({"url": public_url}, indent=2, ensure_ascii=False)) ``` ### Technical Analysis The helper reads the entire user-selected image and explicitly requests `public-read` access. It then removes the presigned query string and returns the base object URL, making public accessibility part of the intended workflow. The implementation does not: - Ask for explicit confirmation immediately before public upload - Validate that the presigned URL belongs to an approved storage host - Enforce a maximum file size - Verify the file signature matches the extension - ...[truncated 1232 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/onboarding.py:364
Finding

Onboarding grants account and payment capabilities beyond the Skill’s market-research purpose

Content
View full analysis
dict: resp = _login_post("/user/v3/web/login", { "type": "sms", "method": "login", "systemId": "LinkFoxAgent", "data": { "areaCode": "+86", "authPhone": phone, "authCode": code, "sourceChannel": channel or "skill", }, }) ``` It then enumerates user/team information and generates an API token: ```python def login_and_get_key(phone: str, code: str, channel: str) -> dict: lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} if lg.get("is_new_user"): lbt = _login_by_token(lg["access_token"], lg["refresh_token"]) 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"] ) ``` The same script supports financial operations: ```python def _cmd_order(args) -> int: try: pkgs = fetch_packages( 7 if bool(fetch_user_info().get("isTeamUser")) else 1 ) match = next( ( n for n in (normalize_package(p) for p in pkgs) if n and n["plan_id"] == args.plan_id ), None, ) order = create_order(args.plan_id, args.method) except (RuntimeError, ValueError) as e: _emit({"error": True, "message": str(e)}) return 1 qr = render_qr(order["qr_content"], session_dir()) order["png_path"] = qr.get("png_p ...[truncated 2108 chars]
Remediation
View remediation

other

Warning
Location
SKILL.md:136
Finding

Skill instructions direct automatic transmission of inferred user feedback to a separate service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/damai_mercado_market_intelligence.py:89
Finding

Complete API responses are retained in unexpected fallback locations with default permissions

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

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 multiple headers populated directly from environment variables, and the destination base URL is also controllable via LINKFOX_TOOL_GATEWAY. In this skill context, that can leak sensitive session metadata and the API key to an attacker-controlled endpoint if the environment is poisoned or the skill runs in an untrusted execution environment, creating a real SSRF/credential exfiltration risk.

Content

Scanner excerpt · scripts/damai_mercado_market_intelligence.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 script allows base URLs for login and agent-user APIs to be overridden via environment variables and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those endpoints. In an agent/skill environment where outer orchestration can influence environment variables, this creates a credential exfiltration and SSRF-style risk if a malicious or compromised runtime redirects traffic to attacker-controlled hosts.

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

Gateway requests use a URL derived from environment-controlled base configuration and attach the LinkFox API key in the Authorization header. If an attacker can set or influence LINKFOX_AGENT_API_URL or fallback variables, requests may be sent to an arbitrary host, leaking credentials and enabling unintended outbound access.

Content

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

python
headers["Content-Type"] = "application/json"
        req = Request(url, method=method, data=body_bytes, headers=headers)
        try:
            with urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            status = e.code

Tainted flow: 'req' from os.environ.get (line 57, 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/upload_image.py (reported line 73)May include surrounding context.

python
)

    try:
        with urlopen(req, timeout=150) as response:
            result = json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The code performs an HTTP PUT to a presigned URL returned by a remote service, and that URL is not validated against an allowlist or expected host pattern before upload. If the presign endpoint is compromised, misconfigured, or redirected via a malicious LINKFOX_TOOL_GATEWAY setting, local file contents could be exfiltrated to an arbitrary external destination.

Content

Scanner excerpt · scripts/upload_image.py (reported line 106)May include surrounding context.

python
)

    try:
        with urlopen(req, timeout=150) as response:
            if response.status not in (200, 201):
                print(f"Upload failed with status: {response.status}", file=sys.stderr)
                sys.exit(1)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill advertises product research but also supports local image upload to object storage and generation of public URLs, which is a distinct data-handling operation with privacy implications. Uploading local files expands the attack surface from read-only market queries to exfiltration of user-provided local content, especially if users do not clearly understand that a public link will be created.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill advertises product research but also supports local image upload to object storage and generation of public URLs, which is a distinct data-handling operation with privacy implications. Uploading local files expands the attack surface from read-only market queries to exfiltration of user-provided local content, especially if users do not clearly understand that a public link will be created.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill advertises product research but also supports local image upload to object storage and generation of public URLs, which is a distinct data-handling operation with privacy implications. Uploading local files expands the attack surface from read-only market queries to exfiltration of user-provided local content, especially if users do not clearly understand that a public link will be created.

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

python scripts/damai_mercado_market_intelligence.py '{"toolName":"product_sales_trend","arguments":{"market_code":"MLM","sku_id":"MLM1602785195","days":90}}'

text

## Display Rules

1. Present only fields supported by the response; do not invent demand, profit, or competition conclusions.
2. State the market, filters, time coverage, record count, currency, and pagination when available.

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

The skill is described as a Mercado Libre market-intelligence/query capability, but this script performs account onboarding, SMS login, API key issuance, package discovery, and payment/order handling. That mismatch materially expands privilege and data-handling scope, increasing the chance users or calling agents trigger credential collection and account actions they would not reasonably expect from a research/query skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code can create orders and generate payment QR codes, which is unrelated to the stated market-research purpose and introduces financial-action capability. In an agentic context, unnecessary purchase flows are dangerous because they can facilitate unauthorized charges, social engineering, or misleading prompts to complete payment.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares capabilities that include environment access, file writes, and network use, but it does not define an explicit tool scope or allowed-tools boundary. In an agent setting, that omission weakens least-privilege controls and makes it harder to prevent unintended filesystem, secret, or outbound-network access if the implementation drifts or is abused.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Line L032 states that category and product keywords must use the selected market's local language. This is a language/locale constraint expressed as a requirement, but the document does not offer the user a choice or frame it as an opt-in behavior, which conflicts with the policy against forcing a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill mandates writing complete responses to session-scoped local files, even when those responses may include user-provided content, account metadata, or other unnecessary details. Persistent storage increases exposure through local compromise, accidental commits, over-retention, or cross-task data leakage, especially because it is always-on rather than narrowly justified.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Automatically reporting user praise, dissatisfaction, or intent mismatches to a Feedback API is not necessary for fulfilling market-intelligence queries and results in unneeded transmission of interaction metadata. That creates privacy and data-governance risk because user behavior and context may be shared with another endpoint without explicit, informed consent.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The feedback rule directs the agent to send user interaction details to another API whenever sentiment or intent mismatch is detected. That is a form of behavioral telemetry export and can leak contextual user information unrelated to the requested market-analysis function.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The parameter description states query must be a local-language category keyword, which imposes a language requirement in the skill documentation. The file does not offer a user opt-in or explain that the constraint is a justified region-specific requirement, so it reads as a language policy restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The keyword field is described as requiring a local-language product keyword, which is a natural-language constraint. Because the file does not present this as optional or explicitly justified by upstream service requirements, it may violate the language/locale policy.

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

空结果、data_available=false 或覆盖不足提示通常是正常业务结果,不等同于系统故障。

curl 示例

bash
curl -X POST "${LINKFOX_TOOL_GATEWAY}/damai/call" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The onboarding flow explicitly asks the user to provide a phone number so a local script can register on their behalf, but it gives no privacy notice, consent language, retention limits, or guidance on safe handling of that personal data. In an agent setting, this increases the risk of unnecessary collection, logging, or exposure of phone numbers and one-time codes during troubleshooting.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to persist an API key in shell startup files and environment settings without warning that these locations may be readable by other local users, copied into backups, exposed through shell history, or inherited by unrelated processes. Persisting long-lived credentials this way expands the exposure window and can lead to credential theft if the host is shared or compromised.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module documentation explicitly says writing to /tmp is forbidden and that unwritable current directories should cause an error, but the implementation silently falls back to home and temp directories. This mismatch can cause sensitive API responses to be persisted in locations with weaker isolation or different retention properties than operators expect, increasing accidental data exposure risk.

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 writes the full API response to disk, including potentially sensitive market data, comments, images metadata, and any returned identifiers, regardless of response size. In an agent-skill setting, automatic persistence expands the data exposure surface because later users, tools, or processes on the same host may access these files without the caller realizing the data was retained.

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