Back to skill

Security audit

亚马逊竞品动态监控专家

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly fits Amazon competitor monitoring, but it bundles broad account, billing, upload, and recurring-task powers with credential-bearing network calls that deserve human review before installation.

Install only if you trust LinkFox with Amazon competitor data, API keys, account onboarding, and paid-credit workflows. Keep LINKFOX_TOOL_GATEWAY and related endpoint variables unset or pointed only at trusted LinkFox hosts, review any payment or recurring-task action before approving it, and do not upload local files unless they are safe to make publicly accessible.

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 (160)

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 destination is derived from environment-controlled base URLs via _login_base() and _agent_user_base(), then used with sensitive request bodies and authorization headers. In an agent/runtime environment where env vars can be influenced, this becomes an SSRF/exfiltration primitive that can leak SMS login data, access tokens, refresh tokens, and issued API keys to an attacker-controlled endpoint.

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 URL is built from environment-derived _agent_base() and then passed to urlopen with the API key in the Authorization header. If the environment variable is poisoned, the script will transmit the API key and order/account operations to an attacker-controlled server, enabling credential theft and unauthorized account interaction.

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 via helper functions and then used to send login data, SMS requests, access tokens, and API-token generation traffic. In a hostile or multi-tenant runtime, an attacker who can influence those environment variables can redirect these authenticated requests to an attacker-controlled endpoint, causing credential and token exfiltration.

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 built from environment-controlled base configuration and used with an Authorization header containing the LinkFox API key. If an attacker can set LINKFOX_AGENT_API_URL or related variables, requests and API keys can be redirected to attacker infrastructure, exposing credentials and enabling 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
93% confidence
Finding
The destination URL for requests.post is derived from helper functions that read environment variables for the base API endpoints. In a hostile or misconfigured runtime, an attacker can redirect login and token requests to attacker-controlled infrastructure, causing SMS login credentials, access tokens, refresh tokens, and generated API keys to be exfiltrated.

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 urllib gateway request is built from a base URL taken from environment variables, then automatically includes the LinkFox API key in the Authorization header. If the environment is attacker-influenced, requests can be silently redirected to an untrusted server, exposing the API key and any account/order metadata sent in the request.

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
91% confidence
Finding
The script builds request destinations from environment-controlled base URLs and then sends highly sensitive data to them via requests.post, including phone numbers, SMS codes, access tokens, refresh tokens, and derived API-token operations. If an attacker can influence environment variables in the host runtime, they can redirect these authentication flows to an attacker-controlled endpoint and capture credentials or tokens.

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 URL is also derived from environment variables and used in urlopen with the Authorization header containing the API key. A compromised or attacker-influenced environment could redirect these calls to an external server and exfiltrate the API key as well as user/account/order metadata.

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
93% confidence
Finding
The request sent to urlopen includes attacker-influenced environment-derived values such as LINKFOX_TOOL_GATEWAY, SESSION_ID, MODE_ID, APP_NAME, and the API key header. Because the destination host can be overridden by environment variable, the script can be induced to exfiltrate credentials and task metadata to an arbitrary server, making this a real SSRF/exfiltration risk rather than a harmless network call.

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 destination is derived from environment-controlled base URLs and the request may include sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys in headers or bodies. If an attacker can influence environment variables in the host or workspace, they can redirect these requests to attacker-controlled infrastructure and exfiltrate credentials.

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 request URL is built from environment-controlled base URLs and then invoked with an Authorization header carrying the API key. A hostile environment setting can redirect authenticated requests, exposing the API key and enabling unauthorized account, package, and order operations.

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
92% 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 API-token requests to those endpoints. If an attacker can influence environment variables, they can redirect authentication traffic to an attacker-controlled server and exfiltrate credentials and issued tokens.

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
89% confidence
Finding
The gateway request uses a URL derived from environment variables and includes the API key in the Authorization header. An attacker who controls LINKFOX_AGENT_API_URL or fallback variables can cause the tool to send the bearer credential to an untrusted host, resulting in credential theft and misuse of the victim 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
93% confidence
Finding
The script constructs request destinations from environment-controlled base URLs and then sends sensitive data to them via requests.post. Because this file handles SMS login, access tokens, refresh tokens, API key generation, and account metadata, a poisoned environment can redirect those secrets to an attacker-controlled host, creating a server-side exfiltration path.

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 URL is derived from environment variables and used by urllib.request.urlopen together with the API key in the Authorization header. An attacker who can influence the runtime environment can redirect paid-order, account, and package queries to an untrusted endpoint and capture the API key or manipulate responses.

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 POST destination is derived from helper functions that read environment variables for base URLs, so a hostile runtime can redirect login and token-bearing requests to an attacker-controlled host. Because these requests carry phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, this creates a clear exfiltration and credential-theft path.

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 constructed from environment-controlled base URLs and then passed to urlopen with the API key in the Authorization header. An attacker who can influence environment variables can force authenticated requests to an arbitrary server and capture the API key and account data.

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
93% confidence
Finding
The request sent via urlopen includes headers and destination data derived from environment variables, notably the API key and an overridable LINKFOX_TOOL_GATEWAY base URL. In this skill context, allowing the gateway URL to be controlled by the environment can redirect authenticated requests to an attacker-controlled host, causing credential exfiltration and leakage of user-supplied query data.

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

Critical
Category
Data Flow
Content
req = Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
    try:
        with urlopen(req, timeout=timeout) as resp:
            # 从 Content-Type 进一步修正扩展名
            if guessed_ext == "bin":
                ct = resp.headers.get("Content-Type", "")
Confidence
95% confidence
Finding
`download_media()` performs arbitrary outbound requests to any attacker-controlled HTTP/HTTPS URL and stores the response locally. Although it blocks `file://` URLs, it still enables SSRF-style access to internal network resources or retrieval of untrusted content if upstream callers pass unsanitized URLs.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill describes capabilities requiring environment access, filesystem read/write, and network use, but does not declare permissions or present boundaries to the user. This weakens least-privilege controls and transparency, making it easier for a skill with broad data-handling and reporting functions to access or persist more data than users expect.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill is presented as a focused Amazon competitor-monitoring expert, but its described behavior includes unrelated high-risk capabilities such as SMS-code login, API key retrieval, package purchase/payment flows, file upload to OSS, and generic scheduler management. This mismatch is dangerous because users may authorize a narrow business-analysis workflow while the skill can trigger account, payment, credential, and data-transfer actions outside that expectation.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The skill documentation instructs agents to automatically chain this text-generation skill into downstream image/video generation workflows without requiring an explicit user request for those additional actions. This expands the skill’s effective scope beyond its stated purpose and can cause unintended external service calls, additional data propagation, and execution of side effects the user did not clearly authorize.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The document simultaneously states that image/video generation is 'not applicable' for this skill while also directing agents to invoke those downstream skills automatically. This contradiction is dangerous because it undermines policy clarity, makes guardrails unreliable, and increases the chance that an agent will perform higher-impact actions despite user-facing language suggesting otherwise.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The file documents an AI text-generation API under a skill context described as Amazon competitor monitoring, which is a strong scope mismatch. Such capability drift is dangerous because it can enable unreviewed outbound data flows and hidden functionality beyond the user’s expected purpose, especially when prompts, media URLs, and identifiers are sent to a remote service.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The standalone public feedback endpoint is unrelated to competitor monitoring and sends content to a separate external base URL. Unjustified extra egress paths increase the risk of unintended data disclosure, misuse of user-generated content, and expansion of the skill’s effective behavior beyond what users or reviewers would reasonably expect.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
skills/linkfox-task-scheduler/references/api.md:57