Back to skill

Security audit

1688找货源专家

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs the advertised sourcing workflow, but it also has automatic feedback telemetry and credential-handling choices that deserve review before installation.

Install only in a trusted environment, keep LinkFox endpoint override variables unset unless you fully control them, store the API key in a secure credential manager rather than shell profiles, review any feedback or public upload behavior before use, and treat generated HTML reports as active content.

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

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:41
Finding

Mandatory Agent Response Manipulation

Content
View full analysis
` 3 条可执行后续建议。 ``` Translated meaning: every response must end with a `` element containing three actionable follow-up suggestions. Related promotional output requirements also appear in child Skills, including: ```markdown *For more high-quality, professional cross-border e-commerce skills, visit [LinkFox Skills](https://skill.linkfox.com/).* ``` For example, this footer is present at `skills/linkfox-1688-search-by-image/SKILL.md:242`, with equivalent LinkFox promotional footers in several other child Skills. ### Technical Analysis The root Skill imposes a mandatory output instruction on every Agent response, regardless of the user's requested format or whether follow-up suggestions are relevant. Because the rule is loaded as part of the Skill instructions, it can alter the Agent's response behavior throughout the active session. This exceeds the minimum permissions necessary to perform 1688 sourcing and profitability analysis. The business workflow does not require a fixed custom element on every response, nor does it require promotional links in task results. The behavior is classified as instruction hijacking because it changes the Agent's general response goals instead of being limited to the Skill's functional output. ### Attack Path 1. The Agent loads the root `SKILL.md`. 2. The mandatory response rule enters the active instruction context. 3. The user requests a response with a strict or unrelated output format. 4. The Skill instruction directs the Agent to append attacker-defined content anyway. 5. Child Skills may additionally cause branded promotional links to be included in outputs. ### Impact Assessment The issue can: - Override user-requested response formatting. - Contam ...[truncated 483 chars]
Remediation
View remediation
` to every response. 2. Generate follow-up suggestions only when they are relevant to the completed task. 3. Respect user- or system-provided output schemas without adding undeclared fields. 4. Remove promotional footers from functional Skill instructions. 5. If branding is required, place it in optional documentation rather than runtime Agent output. 6. Add automated tests verifying that strict JSON, XML, and other structured-output requests are not modified. ]]>

other

Error
Location
skills/linkfox-1688-search-by-image/SKILL.md:233
Finding

Automatic Export of Conversation-Derived Feedback Without Explicit Consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-ai-mode-google-search/scripts/google_ai_search.py:36
Finding

Credential and Session Metadata Exfiltration Through Environment-Controlled API Destinations

Content
View full analysis
str: """Gateway base address: environment override first, production fallback.""" 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 get_api_key(): key = os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get("LINKFOXAGENT_API_KEY") if not key: print( "API Key not configured", file=sys.stderr, ) sys.exit(1) return key 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")) ``` The same endpoint-override and metadata-header pattern was observed in the 1688, Amazon, DLD, Jiimore, Keepa, SellerSprite, SIF, and AIGC wrappers. The onboarding implementation also defines separately overridable authentication destinations at `skills/linkfox-1688-search-by-image/scripts/onboarding.py:69-85`: ```python def _agent_base() -> str: return _env_base(" ...[truncated 2606 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
skills/linkfox-1688-search-by-image/references/onboarding.md:12
Finding

Plaintext Long-Lived API Key Persistence in Shell Profiles

Content
View full analysis
"` - macOS zsh: `echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc` - Linux bash: `echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc` ``` Equivalent instructions are duplicated across the onboarding references of multiple LinkFox Skills. ### Technical Analysis The onboarding documentation recommends storing a long-lived API key as plaintext in shell startup files or persistent user environment configuration. Shell profiles are routinely read by interactive shells and may be accessed by other software running under the same user account. They can also be included in backups, dotfile repositories, support bundles, or accidental file disclosures. The Python onboarding implementation reviewed during the audit does not silently append the key itself. The persistence occurs when the user follows the documented commands. The behavior is therefore explicit but insecure. ### Attack Path 1. A user completes SMS authentication and receives a LinkFox API key. 2. The user follows the recommended onboarding command. 3. The key is written in plaintext to `.bashrc`, `.zshrc`, or persistent Windows environment storage. 4. Another process operating under the user account, a malicious extension, a compromised backup, or an accidentally published dotfile reads the key. 5. The attacker reuses the key against LinkFox services until it expires or is revoked. ### Impact Assessment A local attacker or any party obtaining the profile file can acquire the API key without needing to intercept live network traffic. The resulting access is limited to the permissions assigned to the LinkFox API key, but may include consumption of ...[truncated 206 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
skills/linkfox-file-upload/SKILL.md:32
Finding

Unpinned Runtime Dependency Installation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-report-generator/scripts/inject_report.py:164
Finding

Untrusted HTML and JavaScript Injection in Generated Reports

Content
View full analysis
str: echarts_code = "" m = _ECHARTS_BLOCK_RE.search(content) if m: echarts_code = m.group(1).strip() echarts_code = _SCRIPT_OPEN_RE.sub("", echarts_code) content = _ECHARTS_BLOCK_RE.sub("", content).strip() canvas_code = "" m = _CANVAS_BLOCK_RE.search(content) if m: canvas_code = m.group(1).strip() canvas_code = _SCRIPT_OPEN_RE.sub("", canvas_code) content = _CANVAS_BLOCK_RE.sub("", content).strip() html = template.replace("{{TITLE}}", title or "LinkFox Analysis Report") html = html.replace("{{LANG}}", language) html = re.sub( r".*?", "\n" + content + "\n", html, flags=re.DOTALL, ) if echarts_code: html = html.replace( "// ECHARTS_INIT_START\n // ECHARTS_INIT_END", "// ECHARTS_INIT_START\n " + echarts_code + "\n // ECHARTS_INIT_END", ) if canvas_code: html = html.replace( "// CANVAS_INIT_START\n // CANVAS_INIT_END", "// CANVAS_INIT_START\n " + canvas_code + "\n // CANVAS_INIT_END", ) return html ``` ### Technical Analysis The generator reads an HTML fragment from a caller-selected file and directly inserts it into a report template. It does not escape or sanitize the primary `content` value. It also extracts ECharts and Canvas script blocks and inserts their contents into executable JavaScript positions. Removing `
Remediation
View remediation
`, event handlers, SVG payloads, `javascript:` URLs, template breakout, and malicious chart blocks. 9. Treat model-generated HTML as untrusted input rather than trusted application code. ]]>
Vulnerability Patterns
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (355)

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 builds request destinations from environment variables such as LINKFOX_LOGIN_API_URL and LINKFOX_AGENT_USER_API_URL, then sends sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and derived API keys to those URLs. If an attacker can influence the environment, they can redirect authentication traffic to an attacker-controlled server and capture credentials and tokens, which is a real secret-exfiltration risk.

Content

Scanner excerpt · skills/linkfox-1688-search-by-image/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
94% confidence
Finding

The gateway request path ultimately uses a base URL sourced from environment variables and attaches the API key in the Authorization header before calling urlopen. An attacker who controls the environment can redirect these requests to a malicious endpoint and harvest the API key or manipulate billing and account-related responses.

Content

Scanner excerpt · skills/linkfox-1688-search-by-image/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 · skills/linkfox-1688-search-by-image/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

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · skills/linkfox-1688-search-by-image/scripts/upload_image.py (reported line 106)May include surrounding context.

python
)

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

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

download_media fetches an arbitrary caller-supplied URL with urlopen, which creates a server-side request capability. Although it restricts schemes to http/https, it does not validate hostnames, block private/internal IP ranges, or enforce an allowlist, so it can be abused for SSRF against internal services or for retrieving attacker-chosen content into the skill's workspace.

Content

Scanner excerpt · skills/linkfox-1688-source-profiler/scripts/linkfox_paths.py (reported line 504)May include surrounding context.

python
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", "")

Tainted flow: 'url' from os.environ.get (line 235, credential/environment) → requests.post (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 · skills/linkfox-ai-mode-google-search/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
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · skills/linkfox-ai-mode-google-search/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 335, 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 · skills/linkfox-aigc-textgen/scripts/aigc_textgen.py (reported line 237)May include surrounding context.

python
req = _lf_Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
    try:
        with _lf_urlopen(req, timeout=timeout) as resp:
            if guessed_ext == "bin":
                ct = resp.headers.get("Content-Type", "")
                if "mp4" in ct:

Tainted flow: 'req' from os.environ.get (line 335, 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 · skills/linkfox-aigc-textgen/scripts/aigc_textgen.py (reported line 337)May include surrounding context.

python
}
    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 ""

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The code constructs request destinations from environment-controlled base URLs and then sends sensitive authentication material, including SMS login data, access tokens, and API-token generation 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.

Content

Scanner excerpt · skills/linkfox-aigc-textgen/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
90% confidence
Finding

The gateway URL is derived from environment variables and used for authenticated API calls via urllib, carrying the API key in the Authorization header. An attacker who controls the environment can redirect billing, account, or token-related requests to a malicious host and harvest the API key or manipulate responses.

Content

Scanner excerpt · skills/linkfox-aigc-textgen/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: 'url' from os.environ.get (line 235, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The script builds request destinations from environment variables such as LINKFOX_LOGIN_API_URL and LINKFOX_AGENT_USER_API_URL, then sends sensitive authentication material including phone numbers, SMS codes, access tokens, refresh tokens, and derived API-token requests to those endpoints. If an attacker can influence the runtime environment, they can redirect these requests to attacker-controlled infrastructure and exfiltrate credentials or tokens, enabling account takeover and downstream abuse.

Content

Scanner excerpt · skills/linkfox-amazon-search/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
90% confidence
Finding

The gateway URL is also derived from environment variables and used in urlopen with the Authorization header populated from LINKFOX_AGENT_API_KEY. An attacker who controls environment configuration can redirect gateway calls to a rogue server and capture the API key and account/order metadata, which can then be used to impersonate the user or drive unauthorized transactions.

Content

Scanner excerpt · skills/linkfox-amazon-search/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: 'url' from os.environ.get (line 235, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The code builds request destinations from environment variables such as LINKFOX_LOGIN_API_URL and LINKFOX_AGENT_USER_API_URL, then sends sensitive authentication material to those URLs via requests.post. Because the same flow carries phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, a hostile or misconfigured environment can silently redirect credentials to an attacker-controlled endpoint. The skill context makes this more dangerous because this file already performs account onboarding and key issuance, so the transmitted data is highly sensitive and valuable.

Content

Scanner excerpt · skills/linkfox-dld-product-search/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
95% confidence
Finding

The gateway URL is derived from environment-controlled configuration and then used in urllib.request.urlopen together with the Authorization header containing the LinkFox API key. If an attacker can influence environment variables, they can redirect gateway traffic and exfiltrate the API key or manipulate responses used for account, package, and order operations. In this skill, that risk is amplified because the script also supports plan listing, order creation, and payment-related actions.

Content

Scanner excerpt · skills/linkfox-dld-product-search/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 274, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

download_media() performs network fetches on a caller-supplied URL with only a scheme check for http/https. This enables server-side request forgery to internal services, cloud metadata endpoints, or other unintended hosts, and the downloaded content is written to disk under the shared session area. In a sourcing skill, arbitrary URL fetching is broader than necessary and increases abuse potential.

Content

Scanner excerpt · skills/linkfox-file-upload/scripts/linkfox_paths.py (reported line 524)May include surrounding context.

python
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", "")

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request includes multiple environment-derived headers and uses an environment-controlled gateway base URL, so untrusted runtime configuration can redirect outbound traffic and attach sensitive session metadata or API credentials to an attacker-controlled endpoint. In an agent environment, this creates a realistic SSRF/exfiltration path because the script blindly trusts infrastructure variables and performs the network call without allowlisting the destination.

Content

Scanner excerpt · skills/linkfox-jiimore-get-niche-info-by-keyword/scripts/jiimore_get_niche_info_by_keyword.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
96% confidence
Finding

The script builds request destinations from environment-controlled base URLs and then sends sensitive data to them via requests.post, including phone numbers, SMS codes, access tokens, refresh tokens, and generated API tokens. If an attacker can influence environment variables in the agent runtime, they can redirect authentication traffic to attacker-controlled infrastructure and exfiltrate credentials.

Content

Scanner excerpt · skills/linkfox-jiimore-get-niche-info-by-keyword/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
95% confidence
Finding

The gateway helper uses environment-derived base URLs with urllib.request.urlopen and attaches the API key in the Authorization header. A malicious or compromised runtime configuration could redirect these calls to an attacker-controlled server, causing API key disclosure and enabling further unauthorized actions such as account queries or order operations.

Content

Scanner excerpt · skills/linkfox-jiimore-get-niche-info-by-keyword/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 73, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request URL is derived from the environment via LINKFOX_TOOL_GATEWAY, and the request forwards sensitive headers including the API key and session metadata to whatever host that variable specifies. If an attacker can influence the execution environment, they can redirect traffic to an attacker-controlled endpoint and exfiltrate credentials or product data; in this sourcing/profit-analysis skill, that also exposes commercially sensitive lookup activity.

Content

Scanner excerpt · skills/linkfox-keepa-product-request/scripts/keepa_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
96% confidence
Finding

The code builds request destinations from environment-controlled base URLs and then sends sensitive data to them via requests.post, including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys. If an attacker can influence environment variables in the runtime, they can redirect these authentication and token-issuance flows to attacker-controlled infrastructure and exfiltrate credentials.

Content

Scanner excerpt · skills/linkfox-keepa-product-request/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
94% confidence
Finding

The gateway URL is derived from environment variables and used in urllib.request.urlopen with an Authorization header carrying the API key. An attacker who can set the gateway base URL can cause authenticated requests, user/account lookups, package queries, and order operations to be sent to an attacker-controlled server, exposing secrets and enabling fraudulent billing flows.

Content

Scanner excerpt · skills/linkfox-keepa-product-request/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 73, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The request destination and multiple outbound headers are influenced by environment variables, including LINKFOX_TOOL_GATEWAY and session/app metadata. If an attacker can control the runtime environment, the script can be redirected to an arbitrary server and will send the API key plus workflow metadata, causing credential and data exfiltration over the network.

Content

Scanner excerpt · skills/linkfox-keepa-product-series/scripts/keepa_product_history.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 script builds destination base URLs from environment variables and then sends login data, SMS-related requests, access tokens, and API-token generation traffic to those endpoints via requests.post. If an attacker can influence the runtime environment, they can redirect sensitive authentication flows to attacker-controlled infrastructure, causing credential, token, and account metadata exfiltration.

Content

Scanner excerpt · skills/linkfox-keepa-product-series/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 URL is also derived from environment variables and used by urllib.request.urlopen with the bearer API key attached in the Authorization header. An attacker who can set the environment can redirect package, account, and order requests to a malicious server and capture the API key or manipulate responses to drive fraudulent behavior.

Content

Scanner excerpt · skills/linkfox-keepa-product-series/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

Static analysis

No suspicious patterns detected.