Back to skill

Security audit

跨文化选品专家

Security checks across malware telemetry and agentic risk

Overview

The skill is mostly coherent for product research, but it has under-scoped credential handling and automatic external feedback reporting that users should review before installing.

Review this before installing if you will use real LinkFox credentials, phone/SMS login, billing, or private product-research prompts. Avoid setting custom LINKFOX_* gateway/API URL environment variables unless you fully trust the destination, and treat feedback reporting and public file uploads as external data sharing.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (181)

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

Critical
Category
Data Flow
Content
headers={"Content-Type": "application/json", "Authorization": api_token},
        )
        try:
            with urlopen(req, timeout=30) as resp:
                body = json.loads(resp.read().decode())
            break
        except urllib.error.HTTPError as e:
Confidence
93% confidence
Finding
The code reads `LINKFOX_AGENT_API_KEY` from the environment and sends it as an Authorization header to a base URL that can be overridden by `LINKFOX_TOOL_GATEWAY`. If an attacker can influence that environment variable, they can redirect the request to an attacker-controlled server and exfiltrate the API token.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
93% confidence
Finding
The code builds request destinations from environment-controlled base URLs and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API tokens to those endpoints. If an attacker or untrusted host can influence environment variables, they can redirect authentication and credential traffic to attacker-controlled infrastructure, causing credential exfiltration and account compromise.

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

Critical
Category
Data Flow
Content
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
Confidence
93% confidence
Finding
The gateway request path uses an environment-derived base URL and attaches the LinkFox API key in the Authorization header before calling urlopen. A maliciously set environment variable can redirect these authenticated requests to an attacker-controlled server, leaking the API key and enabling misuse of the linked account and billing functions.

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=120) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""
Confidence
95% confidence
Finding
The request sent via urlopen includes environment-derived values in headers, including an API key and session metadata, and the destination host is also overridable via LINKFOX_TOOL_GATEWAY. That creates a real exfiltration risk: if the environment is influenced by an attacker, secrets and task metadata can be transmitted to an attacker-controlled endpoint with no validation or allowlist.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
95% confidence
Finding
The POST target URL is derived from environment-controlled base URLs and the request may carry sensitive credentials such as access tokens, API keys, phone numbers, SMS codes, and user identifiers. If an attacker can influence environment variables, they can redirect these authenticated requests to attacker-controlled infrastructure and exfiltrate secrets or induce unauthorized actions.

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

Critical
Category
Data Flow
Content
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
Confidence
95% confidence
Finding
The urllib request destination is built from environment-controlled API base URLs and includes the Authorization header populated from the agent API key. An attacker who can set these variables can force the script to send bearer credentials and order/account operations to a malicious server, enabling credential theft and misuse.

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

Critical
Category
Data Flow
Content
}
    req = Request(url, data=data, headers=headers, method="POST")
    try:
        with urlopen(req, timeout=HTTP_TIMEOUT) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""
Confidence
92% confidence
Finding
The script builds outbound requests with sensitive headers sourced from environment variables, including the API key and session metadata, and sends them to a base URL that can be overridden by LINKFOX_TOOL_GATEWAY. If an attacker can influence that environment variable or execution context, the skill will transmit credentials to an attacker-controlled endpoint, causing secret exfiltration and unauthorized API use.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
95% confidence
Finding
The code builds request destinations from environment-controlled base URLs and then sends authentication material, SMS-login data, and token-management requests to those endpoints via requests.post. In a skill environment, env vars are part of the trust boundary; if an attacker can influence LINKFOX_*_API_URL values, they can redirect sensitive traffic to attacker-controlled infrastructure and capture phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys.

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

Critical
Category
Data Flow
Content
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
Confidence
95% confidence
Finding
The gateway client constructs a Request using an environment-derived base URL and includes the API key in the Authorization header before calling urlopen. If the environment variable is tampered with, the skill can exfiltrate the user's persistent API key and billing-related requests to an attacker-controlled endpoint, which is especially dangerous because this file also supports order creation and account queries.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
93% confidence
Finding
The POST target URL is derived from environment-controlled base URLs, and the request can carry sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys. If an attacker can influence environment variables, they can redirect these authentication flows to an attacker-controlled endpoint and exfiltrate credentials or payment-related data.

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

Critical
Category
Data Flow
Content
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
Confidence
92% confidence
Finding
The gateway request URL is also built from environment-controlled configuration and is used with the API key from environment variables in the Authorization header. A hostile runtime can repoint the gateway to an attacker server, causing API key leakage and enabling unauthorized account, package, or order operations.

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=120) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""
Confidence
94% confidence
Finding
The request sent to urlopen includes tainted environment-derived data in headers and potentially an environment-controlled base URL via LINKFOX_TOOL_GATEWAY. This means secrets such as the API key, SESSION_ID, MODE_ID, and APP_NAME can be transmitted to an attacker-controlled endpoint if the environment is manipulated, creating a real exfiltration risk.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
93% confidence
Finding
The script builds request destinations from environment-controlled base URLs and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and API-token requests to those endpoints. If an attacker can influence environment variables, they can redirect these requests to attacker-controlled infrastructure and capture credentials or tokens. The risk is elevated because this file’s purpose includes authentication and token issuance, so the transmitted data is highly sensitive.

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

Critical
Category
Data Flow
Content
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
Confidence
90% confidence
Finding
The gateway request path uses an environment-derived base URL and attaches the API key in the Authorization header before calling urlopen. An attacker who can set the base URL can exfiltrate the API key and observe or manipulate account, package, and order traffic, making this a credential-redirection issue rather than a harmless configuration feature.

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

Critical
Category
Data Flow
Content
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 = ""
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 script handles SMS login, access tokens, refresh tokens, and API-key generation, a poisoned environment can silently redirect those secrets to an attacker-controlled host, creating an SSRF/exfiltration channel.

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

Critical
Category
Data Flow
Content
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
Confidence
93% confidence
Finding
The gateway URL is also derived from environment variables and used in urllib.request.urlopen with the bearer API key attached in the Authorization header. An attacker who can influence the runtime environment can redirect these calls to capture the API key or force requests to unintended internal or external services.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
93% confidence
Finding
The code allows API base URLs to be overridden via environment variables and then sends sensitive material such as SMS-login data, access tokens, refresh tokens, uid headers, team identifiers, and API-token requests to those URLs with requests.post. In a hostile or misconfigured runtime, this becomes credential exfiltration or SSRF-to-attacker infrastructure, which is especially dangerous because this file handles account onboarding and token generation rather than ordinary low-sensitivity product-scouting data.

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

Critical
Category
Data Flow
Content
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
Confidence
91% confidence
Finding
The gateway path uses a URL derived from environment variables and attaches the LinkFox API key in the Authorization header before calling urlopen. If an attacker can influence environment configuration, the skill will send the API key and related billing/order traffic to an arbitrary endpoint, enabling secret theft and misuse of the linked account.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
96% confidence
Finding
The POST target URL is derived from environment-controlled base URLs and the request can include sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys. If an attacker can influence environment variables in the host or workspace, the script can be redirected to an attacker-controlled endpoint, causing credential exfiltration and unauthorized account access.

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

Critical
Category
Data Flow
Content
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
Confidence
94% confidence
Finding
The gateway request URL is also built from environment-controlled base URLs, and the request attaches the LINKFOX agent API key in the Authorization header. A malicious or compromised runtime can redirect this traffic to an attacker-controlled server and capture the API key, enabling misuse of the victim's account and paid resources.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill orchestrates multiple tools that can read/write files, access the network, and potentially invoke shell-like capabilities, yet it declares no explicit permissions or trust boundaries. This creates a confused-deputy risk: the agent may perform sensitive actions the user did not reasonably expect, and reviewers cannot verify whether those capabilities are intentionally scoped or overbroad.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill instructs the agent to automatically report user interactions, mismatches, and qualitative feedback to an external Feedback API, which exceeds the stated ABA query-and-analysis function. This creates an unnecessary data egress path that could transmit user content, behavior, or operational context without explicit user consent or a clear minimization policy.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Automatic submission of user feedback and skill-quality assessments to an external API is context-inappropriate for a search-term analytics skill and can leak sensitive business intent, prompts, or user sentiment. Because the reporting is framed as non-interruptive and automatic, it bypasses normal transparency and approval expectations for external data sharing.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The documentation adds a separate public feedback API that is unrelated to the stated ABA intelligent-query/product-scouting function. This expands the skill's effective capability surface and can enable unprompted or user-data-bearing outbound reporting to a different service, which is risky because agents may treat all documented endpoints as approved operational actions.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The onboarding document introduces authentication recovery, scripted registration, and billing/purchase workflows that are unrelated to the declared cross-cultural product-scouting purpose. This kind of scope mismatch is dangerous because it expands the skill into account handling and payment facilitation without a clear need, increasing the chance of abuse, user confusion, and unauthorized collection of credentials or payment-related data.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.