Back to skill

Security audit

亚马逊竞品动态监控专家

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly fits Amazon competitor monitoring, but it bundles broad credentialed network, public upload, report-generation, and response-format behaviors that need user review before installation.

Install only if you trust LinkFox with your API key, Amazon research data, generated reports, uploaded files, and scheduled-agent tasks. Avoid setting custom LinkFox gateway environment variables unless you control the endpoint, do not upload private files, and review generated HTML before sharing it.

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:26
Finding

Mandatory Agent Response Manipulation

Content
View full analysis
` containing three executable follow-up suggestions tailored to the current task. Use statements rather than questions. ``` Several component Skill files also append an unrelated LinkFox promotional link: ```markdown For more high-quality, professional cross-border e-commerce skills, set LinkFox Skills at https://skill.linkfox.com/. ``` Affected promotional-footer locations include: - `skills/linkfox-amazon-product-detail/SKILL.md:189` - `skills/linkfox-amazon-reviews-list/SKILL.md:193` - `skills/linkfox-amazon-search/SKILL.md:206` - `skills/linkfox-amazon-search-by-image/SKILL.md:180` - `skills/linkfox-keepa-product-series/SKILL.md:184` - `skills/linkfox-sellersprite-competitor-lookup/SKILL.md:253` - `skills/linkfox-sif-asin-keywords/SKILL.md:252` ### Technical Analysis The root Skill marks the rule as mandatory and states that violating it constitutes failure. The rule does not merely describe business functionality; it alters every visible Agent response by requiring an attacker-authored output structure. This is persistent within any session where the Skill instructions are loaded. It can interfere with higher-priority output schemas, API response contracts, or user requests for exact output. The promotional footers similarly introduce unrelated vendor-directed content into component Skill behavior. ### Attack Path 1. The Agent loads the root Skill to perform Amazon competitor monitoring. 2. The mandatory-rule section becomes part of the Agent's active instructions. 3. The Agent is directed to append a vendor- ...[truncated 640 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-amazon-product-detail/scripts/amazon_product_detail.py:37
Finding

Credential-Bearing Requests Can Be Redirected to Arbitrary Gateways

Content
View full analysis
str: """Gateway base address: LINKFOX_TOOL_GATEWAY takes precedence.""" return ( os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com" ).rstrip("/") def get_api_url(): sys.path.insert( 0, os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "..", "_shared", ), ) return get_api_base() + API_PATH 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 is 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")) ``` Equivalent endpoint-override behavior was identified in the other LinkFox API clients, including: - `skills/linkfox-aigc-textgen/scripts/aigc_textgen.py` - `skills/linkfox-amazon-reviews-list/scripts/amazon_reviews.py` - `skills/linkfox-amazon-search/scripts/amazon_s ...[truncated 2562 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

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

Persistent HTML and JavaScript Injection in Generated Reports

Content
View full analysis
str: if not os.path.isfile(path): _die(f"--content-file does not exist: {path}", 1) try: with open(path, "r", encoding="utf-8") as f: text = f.read() except OSError as e: _die(f"Unable to read --content-file: {e}", 1) m = _OUTER_FENCE_RE.match(text) if m: text = m.group(1) text = text.strip() if not text: _die("--content-file is empty.", 3) return text def _inject(template: str, content: str, title: str | None, language: str) -> 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 " ...[truncated 2061 chars]
Remediation
View remediation
`, `&`, and script-sensitive Unicode characters in serialized chart data. 8. Add a restrictive Content Security Policy that disallows inline scripts and unapproved network destinations. 9. Host user-generated reports on an isolated origin without access to authentication cookies or sensitive application state. 10. Add regression tests using event-handler, SVG, `javascript:` URL, closing-tag, and chart-block payloads. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
skills/linkfox-file-upload/scripts/linkfox_paths.py:488
Finding

Server-Side Request Forgery and Unbounded Remote Downloads

Content
View full analysis
Optional[str]: from urllib.request import urlopen, Request if not url or not isinstance(url, str): return None if not url.startswith("http://") and not url.startswith("https://"): print( f"[download_media] Unsupported URL scheme: {url[:80]}", file=sys.stderr, ) return None if ts is None: ts = time.time() _, session_dir = _ensure_session(ts) media_dir = os.path.join(session_dir, "media") os.makedirs(media_dir, exist_ok=True) tmp_filename = ( f".tmp-{_safe_slug(slug)}-{int(ts * 1_000_000)}.download" ) tmp_path = os.path.join(media_dir, tmp_filename) req = Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"}) try: with urlopen(req, timeout=timeout) as resp: with open(tmp_path, "wb") as f: while True: chunk = resp.read(65536) if not chunk: break f.write(chunk) ``` Equivalent copies exist in: - `skills/linkfox-report-generator/scripts/linkfox_paths.py` - `skills/linkfox-task-scheduler/scripts/linkfox_paths.py` A similar unrestricted downloader is present in `skills/linkfox-aigc-textgen/scripts/aigc_textgen.py`. ### Technical Analysis The only destination control is a case-sensitive string-prefix check for `http://` or `https://`. The implementation does not reject: - Loopback destinations. - Private or carrier-grade NAT networks. - Link-local and cloud metadata addresses. - Internal hostnames. - IP-literal ...[truncated 1326 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
skills/linkfox-amazon-search-by-image/scripts/upload_image.py:91
Finding

Unvalidated Public Upload Destination Can Disclose Local Files

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
skills/linkfox-aigc-textgen/scripts/onboarding.py:166
Finding

Unpinned Runtime Installation of Third-Party Dependencies

Content
View full analysis
None: if requests is None: raise RuntimeError( "Missing requests dependency. Run: pip install requests" ) ``` The upload implementation similarly instructs installation without a pinned version or integrity hash: ```python try: import oss2 except ImportError: raise RuntimeError( "Missing oss2 dependency. Run: pip install oss2" ) ``` Equivalent onboarding files are duplicated across multiple LinkFox Skills. ### Technical Analysis The instructions install package names from the user's default Python package index without: - Exact version pins. - Cryptographic hashes. - A lockfile. - A controlled package repository. - A reproducible dependency-resolution process. Package installation can execute build-system or installation code. Because the selected package release can change after the Skill has been reviewed, the effective runtime dependency set is mutable. No evidence in the audited package establishes that these named packages are presently malicious. The confirmed issue is the unsafe, unpinned installation mechanism. ### Attack Path 1. A required dependency is absent. 2. The Skill returns an instruction to run an unpinned `pip install` command. 3. The user executes the command using the default configured package index and resolver. 4. The resolver selects whatever release and transitive dependency versions are current at installation time. 5. A compromised release, compromised index, malicious mirror, or future dependency takeover can execute code during installation or import. 6. That code ...[truncated 572 chars]
Remediation
View remediation
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 (290)

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 HTTP client posts to URLs derived from environment-controlled base URLs, and these requests carry sensitive materials such as SMS login data, access tokens, refresh tokens, and generated API keys. If an attacker can influence environment variables, they can redirect traffic to attacker-controlled infrastructure and exfiltrate credentials or capture authentication flows.

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 request path uses urllib to contact a base URL sourced from environment variables while attaching the API key in the Authorization header. An attacker who can set those variables can redirect requests to a malicious server and steal the API key, observe order and account operations, or manipulate responses used by the CLI.

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
94% 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, API keys, and payment-related identifiers to those endpoints. If an attacker can influence environment variables, they can redirect authentication and token-issuance traffic to attacker-controlled infrastructure and capture credentials.

Content

Scanner excerpt · skills/linkfox-amazon-product-detail/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
93% confidence
Finding

The gateway URL is derived from environment variables and used by urllib with the Authorization header populated from the agent API key. An attacker who can set the environment can redirect these requests to a malicious server and exfiltrate the API key and account/order metadata.

Content

Scanner excerpt · skills/linkfox-amazon-product-detail/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 84, 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-amazon-reviews-list/scripts/amazon_reviews.py (reported line 91)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=timeout) as response:
            result = _parse_api_response(response.read(), path)
            cost_token = response.headers.get("X-Cost-Token")
            if isinstance(result, dict) and cost_token is not None:

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 generated API keys to those endpoints. If an attacker can influence the environment, they can redirect authentication traffic and secrets to attacker-controlled infrastructure, turning this onboarding flow into credential exfiltration.

Content

Scanner excerpt · skills/linkfox-amazon-reviews-list/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 also derived from environment variables and used with urlopen together with the Authorization header carrying the LinkFox API key. An attacker who controls LINKFOX_AGENT_API_URL or LINKFOX_TOOL_GATEWAY can redirect API-key-authenticated requests for account info, package listing, and order actions to an attacker endpoint, exposing credentials and enabling phishing-like payment manipulation.

Content

Scanner excerpt · skills/linkfox-amazon-reviews-list/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
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-amazon-product-detail/scripts/amazon_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: 'req' from os.environ.get (line 73, 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-amazon-search-by-image/scripts/amazon_search_by_image.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
91% confidence
Finding

The POST target is derived from environment-controlled base URLs, and the function sends sensitive authentication material such as access tokens, refresh tokens, phone numbers, SMS codes, and generated API tokens to that destination. If an attacker can influence environment variables, they can redirect these requests to an attacker-controlled host and exfiltrate credentials or session data.

Content

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

The gateway request uses a URL built from environment-controlled base configuration and attaches the API key in the Authorization header. An attacker who can set the environment can redirect requests to a malicious endpoint, causing API key leakage and allowing unauthorized use of the victim's account or service balance.

Content

Scanner excerpt · skills/linkfox-amazon-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 58, 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-amazon-search-by-image/scripts/upload_image.py (reported line 74)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 58, 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-amazon-search-by-image/scripts/upload_image.py (reported line 107)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 73, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The request sent via urlopen includes multiple headers derived directly from environment variables, and the destination base URL is also overridable through LINKFOX_TOOL_GATEWAY. In an agent/runtime context, environment variables are part of the execution trust boundary; allowing unvalidated environment-controlled routing and metadata forwarding can exfiltrate API keys, session identifiers, and task metadata to an attacker-controlled endpoint via SSRF-style redirection or malicious gateway override.

Content

Scanner excerpt · skills/linkfox-amazon-search/scripts/amazon_search.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
91% confidence
Finding

The code allows service base URLs to be overridden from environment variables and then sends login data, SMS verification flows, access tokens, refresh tokens, and API-token generation requests to those URLs via requests.post. In a skill or agent runtime where environment can be influenced by an attacker or a misconfigured wrapper, this enables SSRF-like redirection and direct credential exfiltration to attacker-controlled endpoints.

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 client builds a Request using a base URL derived from environment variables and attaches the API key in the Authorization header before calling urlopen. If the environment is attacker-controlled or poisoned, sensitive API credentials and order/account operations can be redirected to an untrusted server, causing credential leakage and unauthorized external access.

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: 'req' from os.environ.get (line 274, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
91% confidence
Finding

download_media accepts an arbitrary caller-supplied URL and fetches it with urlopen, only restricting the scheme to HTTP/HTTPS. This creates SSRF-style behavior: an attacker controlling the URL can cause the agent to connect to internal services, cloud metadata endpoints, or other sensitive network locations and persist the response locally.

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

The request destination and headers are partially derived from environment variables, especially LINKFOX_TOOL_GATEWAY and several metadata headers, and are then sent via urlopen without validation. In an agent/runtime environment where env vars can be influenced by a caller or another component, this can redirect authenticated traffic to an attacker-controlled endpoint and leak the API key and session metadata, effectively creating SSRF plus credential exfiltration risk.

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

The script constructs request destinations from environment-controlled base URLs and then sends sensitive authentication material, including access tokens and generated API keys, to those endpoints. If an attacker can influence environment variables such as LINKFOX_LOGIN_API_URL or LINKFOX_AGENT_USER_API_URL, the tool can be redirected to attacker-controlled servers and exfiltrate credentials during onboarding.

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

The gateway request path uses an environment-derived base URL and automatically attaches the LINKFOX_AGENT_API_KEY in the Authorization header. An attacker who can set LINKFOX_AGENT_API_URL or related fallback variables can redirect these authenticated requests to an arbitrary endpoint and capture the API key and account metadata.

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

Tainted flow: 'req' from os.environ.get (line 274, 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-file-upload/scripts/linkfox_paths.py (reported line 281)May include surrounding context.

python
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:

Tainted flow: 'req' from os.environ.get (line 274, 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-report-generator/scripts/linkfox_paths.py (reported line 281)May include surrounding context.

python
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:

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() performs network fetches on an arbitrary caller-supplied URL and only checks that the scheme is HTTP/HTTPS. That enables SSRF to internal services, cloud metadata endpoints, or other sensitive network locations, and can also be abused to download untrusted large content into the workspace.

Content

Scanner excerpt · skills/linkfox-report-generator/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", "")