Back to skill

Security audit

TRO风险提示专家

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent LinkFox IP-risk workflow, but it includes silent feedback reporting plus credential, endpoint, and persistence patterns users should review before installing.

Install only if you trust LinkFox with the product images, prompts, detection inputs, feedback content, account tokens, and billing-related operations involved. Do not use unreviewed LINKFOX_* endpoint overrides, avoid saving API keys in shell startup files, and treat generated HTML reports as untrusted unless sanitized. Review the automatic feedback behavior carefully because it can send user statements or inferred intent to LinkFox without an explicit prompt at the time of submission.

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
skills/linkfox-ruiguan-copyright-detection/SKILL.md:132
Finding

Silent Transmission of User Feedback and Intent to an External Service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-aigc-textgen/scripts/aigc_textgen.py:323
Finding

Credential-Bearing Requests Can Be Redirected to Arbitrary Environment-Controlled Hosts

Content
View full analysis
str: return _env_base("LINKFOX_LOGIN_API_URL", "https://api.linkfox.com") def _agent_user_base() -> str: return _env_base("LINKFOX_AGENT_USER_API_URL", "https://agent-api.linkfox.com") ``` It then sends authentication material to the selected destinations: ```python resp = _http_post(f"{_agent_user_base()}/account/loginByToken", { "token": access_token, "refreshToken": refresh_token, "device": {"aid": "3026344186", "did": "", "type": "Windows", "os": " ...[truncated 2125 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

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

Generated Reports Allow Unsanitized HTML and JavaScript Injection

Content
View full analysis
str: # 1. Extract ECharts / Canvas blocks 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() # 2. Replace document placeholders html = template.replace("{{TITLE}}", title or "LinkFox Analysis Report") html = html.replace("{{LANG}}", language) # 3. Inject main content html = re.sub( r".*?", "\n" + content + "\n", html, flags=re.DOTALL, ) # 4. Insert ECharts / Canvas initialization code 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", ) ``` ### Technical Analysis The main report fragment is inserted into the template without HTML sanitization. Consequently, it may contain active elements or attributes such as: - `
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
skills/linkfox-ruiguan-copyright-detection/scripts/ruiguan_copyright_detection.py:250
Finding

Unsanitized SESSION_ID Permits Output-Path Traversal

Content
View full analysis
str: """Prefer SESSION_ID; otherwise generate an automatic identifier.""" env = os.environ.get("SESSION_ID") if env: return env.strip() if "_auto" not in _SESSION_CACHE: _SESSION_CACHE["_auto"] = ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3) ) return _SESSION_CACHE["_auto"] def _ensure_session(ts: float) -> tuple[str, str]: """Return (linkfox_root, session_dir); session_dir will exist.""" date_str = time.strftime("%Y-%m-%d", time.localtime(ts)) sid = _session_id(ts) root = _linkfox_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _ensure_meta(root, session_dir, date_str, sid, ts) return root, session_dir ``` ### Technical Analysis `SESSION_ID` is used directly as a filesystem path component without validation. `os.path.join()` does not confine traversal components to the preceding root. Values containing `..`, path separators, drive prefixes, or absolute paths can cause the resulting path to escape the intended session directory. Subsequent code writes metadata, cached responses, generated reports, API output, media files, or QR images beneath the resulting directory. The exact writable target depends on process permissions. ### Attack Path 1. An attacker controls or influences the `SESSION_ID` environment variable. 2. The attacker assigns a traversal or absolute-path value, such as a value containing `../`. 3. A Skill invokes `_ensure_sessio ...[truncated 962 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
skills/linkfox-aigc-textgen/references/onboarding.md:11
Finding

Onboarding Documentation Encourages Plaintext Persistence of Bearer API Keys

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` - Either `LINKFOX_AGENT_API_KEY` or legacy `LINKFOXAGENT_API_KEY` may be used ``` ### Technical Analysis The documented workflow stores a bearer API key in plaintext shell startup files or the persistent user environment. These locations are long-lived and commonly exposed through: - Dotfile repositories. - Home-directory backups. - Support and diagnostic archives. - Shell configuration sharing. - Other local processes or users where permissions are weak. - Child processes that inherit the environment. - Process diagnostics and crash reporting. The instructions do not establish restrictive permissions, expiration, rotation, or revocation. Because the key is a bearer credential, possession may be sufficient for authenticated API use. ### Attack Path 1. A user follows the onboarding instructions. 2. The API key is appended to `.bashrc` or `.zshrc`, or saved through `setx`. 3. A local process, backup system, diagnostic tool, shared account, or accidentally published dotfile obtains the stored value. 4. An attacker extracts the bearer token. 5. The attacker uses it against the LinkFox API until the key is revoked or expires. ### Impact Assessment A stolen key may allow unauthorized API use under the victim's account, including consumption of paid compute credits and access to account-scop ...[truncated 159 chars]
Remediation
View remediation

T08 · Insecure Dependencies

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

Runtime Installation Instructions Use Unpinned Third-Party Dependencies

Content
View full analysis
dict: try: import qrcode except ImportError: err = "Missing qrcode dependency; run: pip install qrcode pillow" print(f"{TAG} render_qr: {err}", file=sys.stderr) return {"png_path": None, "ascii_qr": None, "error": err} ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError( "Missing requests dependency; run: pip install requests" ) ``` ```python try: import oss2 except ImportError: raise RuntimeError("Missing oss2 dependency; run: pip install oss2") ``` ### Technical Analysis The project instructs users to install dependencies using mutable package names without: - Reviewed version pins. - Cryptographic hashes. - A lock file. - An isolated environment requirement. - Explicit package-index provenance. A future compromised release, dependency takeover, or incompatible update would be installed and executed with the user's Python privileges. No evidence was found that the named packages are currently malicious; the confirmed issue is the unsafe dependency acquisition process. ### Attack Path 1. A user invokes a feature whose dependency is unavailable. 2. The Skill displays an unpinned `pip install` command. 3. The user runs the command against the currently configured package index. 4. Pip resolves the latest available package and transitive dependencies at installation time. 5. If a resolved release or package source has been compromised, installation or later import executes attacker-controlled code. 6. That code runs with the privileges of the user's Python environment. ### Impact Assessment ...[truncated 330 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 (250)

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

The POST target is derived from environment-controlled base URLs and is used for login and token-related requests that carry phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys. If an attacker can influence environment variables, the script can be redirected to an attacker-controlled endpoint, causing credential exfiltration and account compromise.

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 URL is also built from environment-controlled configuration and is invoked with the Authorization header containing the API key. A manipulated environment can redirect authenticated requests to an attacker-controlled server, exposing secrets and enabling fraudulent account, package, or order operations.

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

Critical
Category
Data Flow
Confidence
97% confidence
Finding

download_media accepts an arbitrary caller-supplied URL and fetches it over the network with only a scheme check. This creates an SSRF-style primitive that can be abused to make outbound requests to attacker-chosen hosts, including internal or link-local services in environments with network access, and then store the retrieved content 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 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

The download_media function performs arbitrary outbound HTTP/HTTPS fetches on a caller-supplied URL with no allowlist, host validation, or private-address blocking. In an agent environment this creates an SSRF primitive that can be used to probe internal services, access metadata endpoints, or retrieve untrusted content into persistent session storage.

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

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The code builds request destinations from environment-controlled base URLs and 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 environment variables in the agent runtime, they can redirect authentication traffic and credentials to attacker-controlled infrastructure, creating an SSRF-style credential exfiltration path.

Content

Scanner excerpt · skills/linkfox-ruiguan-copyright-detection/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 in urllib requests with the Authorization header populated from the API key. An attacker who can set the base URL can force the CLI to transmit bearer credentials and account/order data to an arbitrary server, compromising the user's account and enabling misuse of paid resources.

Content

Scanner excerpt · skills/linkfox-ruiguan-copyright-detection/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 sent by urlopen includes multiple headers derived directly from environment variables, most importantly LINKFOX_TOOL_GATEWAY for the destination and Authorization/SESSION metadata headers. In an agent or multi-tenant execution environment, attacker-controlled environment variables can redirect requests to an arbitrary host and exfiltrate API keys and session metadata, making this a real SSRF-plus-secret-leak issue rather than a harmless configuration pattern.

Content

Scanner excerpt · skills/linkfox-ruiguan-copyright-detection/scripts/ruiguan_copyright_detection.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 allows API base URLs to be overridden via environment variables and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those URLs via requests.post. In a skill execution environment, a malicious wrapper or compromised runtime could redirect these requests to an attacker-controlled endpoint, causing credential exfiltration. The danger is amplified because this file performs authentication and token provisioning unrelated to the declared advisory purpose.

Content

Scanner excerpt · skills/linkfox-ruiguan-detection-patent-design/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 uses a URL derived from environment variables and attaches the Authorization header containing the API key before calling urlopen. An attacker who can influence the environment can redirect traffic and capture API credentials or manipulate downstream purchase/order operations. Because this skill also supports plan listing, order creation, and payment state queries, the redirected traffic could expose both credentials and billing metadata.

Content

Scanner excerpt · skills/linkfox-ruiguan-detection-patent-design/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
94% confidence
Finding

The request forwards multiple environment-derived values, including a caller-controlled gateway base URL and session metadata headers, directly into an outbound HTTP request. If an attacker can influence environment variables in the agent runtime, they can redirect requests to an arbitrary host and exfiltrate the API key and request payload, making this effectively an SSRF-plus-secret-leak issue.

Content

Scanner excerpt · skills/linkfox-ruiguan-detection-patent-design/scripts/ruiguan_detection_patent_design.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 57, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The upload destination is taken from the presigned URL returned by the gateway and the code uploads the entire local file to that URL without validating the hostname, scheme, or expected storage provider. If the gateway is misconfigured, compromised, or pointed at an attacker-controlled base URL, local image contents can be exfiltrated to an unintended remote service.

Content

Scanner excerpt · skills/linkfox-ruiguan-detection-patent-design/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: '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 to them via requests.post. Because this file handles phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, a tampered environment can silently redirect those secrets to an attacker-controlled endpoint, causing credential exfiltration and account compromise.

Content

Scanner excerpt · skills/linkfox-ruiguan-text-trademark-detection/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 uses urllib with a URL derived from environment variables and attaches the API key in the Authorization header. If the runtime environment is influenced by a malicious actor, outbound requests can be redirected to an arbitrary host, leaking the API key and enabling unauthorized use of the victim's account and billing resources.

Content

Scanner excerpt · skills/linkfox-ruiguan-text-trademark-detection/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 script builds outbound request headers from environment variables including SESSION_ID, MESSAGE_ID, MODE_ID, APP_NAME, and the API key, then sends them to a remote endpoint whose base URL is itself overrideable via LINKFOX_TOOL_GATEWAY. This creates a real exfiltration and SSRF-style risk: a compromised runtime or untrusted environment can redirect requests and leak credentials and session metadata to an attacker-controlled host.

Content

Scanner excerpt · skills/linkfox-ruiguan-text-trademark-detection/scripts/ruiguan_text_trademark_detection.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 script allows network destinations to be derived from environment variables and then sends sensitive authentication material, including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, to those endpoints. In a hostile or multi-tenant runtime, an attacker who can influence environment variables can redirect requests to attacker-controlled infrastructure and harvest credentials.

Content

Scanner excerpt · skills/linkfox-ruiguan-trademark-graphic-detection/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 a URL assembled from environment-controlled base configuration and then performs authenticated requests with the API key in the Authorization header. If the environment is manipulated, the skill can be coerced into exfiltrating the API key and order/account data to an attacker-controlled server.

Content

Scanner excerpt · skills/linkfox-ruiguan-trademark-graphic-detection/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-ruiguan-trademark-graphic-detection/scripts/ruiguan_trademark_graphic_detection.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
93% confidence
Finding

The code builds request destinations from environment-controlled base URLs and then sends sensitive login/API-key traffic with requests.post. In this script, those flows include SMS login, access tokens, refresh tokens, and generated API keys, so an attacker who can influence environment variables can redirect secrets to an attacker-controlled endpoint.

Content

Scanner excerpt · skills/linkfox-ruiguan-utility-patent-detection/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 then used in urllib.request.urlopen with the Authorization header carrying the agent API key. If an attacker can set LINKFOX_AGENT_API_URL or related variables, they can exfiltrate credentials and manipulate order/account responses by acting as the remote service.

Content

Scanner excerpt · skills/linkfox-ruiguan-utility-patent-detection/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
96% confidence
Finding

The request sent to the remote gateway includes multiple headers populated directly from environment variables, and the destination base URL is also overrideable via LINKFOX_TOOL_GATEWAY. In an agent/runtime context, environment variables are often influenced by orchestration or untrusted execution context, so this creates a tainted outbound network flow that can exfiltrate session metadata and API credentials to an attacker-controlled endpoint if the base URL is redirected.

Content

Scanner excerpt · skills/linkfox-ruiguan-utility-patent-detection/scripts/ruiguan_utility_patent_detection.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
93% confidence
Finding

The code builds request destinations from environment variables such as LINKFOX_LOGIN_API_URL and LINKFOX_AGENT_USER_API_URL, then sends authentication data, SMS-login payloads, access tokens, refresh tokens, and API-token requests to those URLs with requests.post. If an attacker can influence the process environment, they can redirect these secrets to attacker-controlled infrastructure, turning this into credential exfiltration and SSRF-style outbound communication.

Content

Scanner excerpt · skills/linkfox-zhihuiya-patent-image-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 = ""

Static analysis

No suspicious patterns detected.