Back to skill

Security audit

Linkfox 亚马逊广告

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Amazon Ads toolkit, but it needs review because it handles ad-account credentials, can change ads and budgets, persists full local outputs, serves reports over local HTTP, and allows secret-bearing requests to configurable gateway URLs.

Install only if you are comfortable giving this skill access to your LinkFox/Amazon Ads authorization flow and allowing it to create or update ads, bids, budgets, and statuses. Keep gateway-related environment variables pointed at trusted LinkFox HTTPS hosts, avoid using this in shared workspaces, treat generated linkfox data files and report temp files as sensitive, and disable report HTTP serving when you do not need a browser download link.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (30)

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

Critical
Category
Data Flow
Content
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 ""
Confidence
94% confidence
Finding
The destination host is overrideable via LINKFOX_TOOL_GATEWAY or AMAZON_ADS_BASE_URL, and the script automatically sends the API key in the Authorization header to that endpoint. In an agent context, environment variables may be influenced by deployment or wrapper processes, so this creates a credential exfiltration path to an attacker-controlled server.

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

Critical
Category
Data Flow
Content
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 ""
Confidence
92% confidence
Finding
The request target is derived from environment-controlled base URL configuration and the request includes the Authorization API key header. If an attacker can influence LINKFOX_TOOL_GATEWAY or AMAZON_ADS_BASE_URL, the script will send the credential to an arbitrary endpoint, enabling credential exfiltration or SSRF-like outbound access. In this auth-related skill, that context makes the issue more dangerous because the transmitted secret grants access to authorized store/account data.

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

Critical
Category
Data Flow
Content
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 ""
Confidence
93% confidence
Finding
The request destination is derived from environment-controlled base URL settings and then used in urlopen while sending an Authorization header containing the API key. If an attacker can influence LINKFOX_TOOL_GATEWAY or AMAZON_ADS_BASE_URL, they can redirect the request to an arbitrary host and exfiltrate credentials or sensitive profile data; the skill context makes this more dangerous because it is explicitly an auth-related script handling privileged API access.

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

Critical
Category
Data Flow
Content
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 ""
Confidence
96% confidence
Finding
The request destination is derived from environment-controlled base URL configuration and then used in urlopen while attaching the API key in the Authorization header. If an attacker can influence LINKFOX_TOOL_GATEWAY or AMAZON_ADS_BASE_URL, they can redirect the token refresh request and exfiltrate credentials and token-related data to an arbitrary endpoint.

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

Critical
Category
Data Flow
Content
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 ""
Confidence
96% confidence
Finding
The request target is derived from environment-controlled configuration (LINKFOX_TOOL_GATEWAY or AMAZON_ADS_BASE_URL) and is used directly in urlopen while sending the Authorization API key header. In an agent/skill context, allowing the destination host to be overridden can exfiltrate credentials and token-related responses to an attacker-controlled server, especially because this script is specifically designed to retrieve sensitive auth tokens.

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

Critical
Category
Data Flow
Content
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""
Confidence
89% confidence
Finding
The code allows network destinations to be overridden by environment variables and then sends sensitive data, including phone numbers, SMS codes, access tokens, refresh tokens, and API-token requests, to those URLs via requests.post. In a skill/runtime environment where env vars can be influenced by a host, wrapper, or attacker, this becomes a credential exfiltration path and effectively an SSRF-style outbound sink for secrets.

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

Critical
Category
Data Flow
Content
headers["Content-Type"] = "application/json"
        req = Request(url, method=method, data=body_bytes, headers=headers)
        try:
            with urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            status = e.code
Confidence
87% confidence
Finding
The gateway URL is derived from environment-controlled base URLs and used in urllib.request.urlopen with the Authorization header populated from the environment API key. If an attacker can set LINKFOX_AGENT_API_URL or its fallback, the skill will transmit the API key and related account/order data to an attacker-controlled server.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The skill explicitly states that report data is exposed via a temporary local HTTP server on 127.0.0.1. Even though it binds to localhost, this unnecessarily expands the data exposure surface for potentially sensitive advertising reports and could allow other local processes, browser contexts, or malware on the host to access the extracted JSON during the serving window.

Intent-Code Divergence

Medium
Confidence
85% confidence
Finding
The module description says it only generates an authorization URL, but the code also persists that URL to disk and copies it to the system clipboard. This hidden behavior increases exposure of a sensitive OAuth authorization link, especially on shared systems where clipboard contents and temporary files may be accessed by other users or processes.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The skill explicitly permits overriding the token refresh API base URL via environment variables. In a skill that handles API keys and refresh flows, this materially increases SSRF-style redirection and credential exfiltration risk because the script will POST sensitive data and the Authorization header to whatever endpoint is configured.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The module is documented as shared plumbing for list scripts, but it also includes mutation helpers and a persistent output layer that writes full responses and metadata to disk. This hidden expansion of capability increases the risk that a caller uses write operations or local persistence unintentionally, especially in an agent-skill context where operators may assume read-only behavior.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The comments describe the output layer as having 'no cache', but the implementation persistently stores full responses and session metadata under a local linkfox directory. Misleading comments can cause operators and downstream code to underestimate data retention, leading to sensitive advertising or token-adjacent data being written to disk without proper handling.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The script validates and constructs an ad-type-specific endpoint (`sb/v4/ads/{adType}`) and declares `METHOD = POST`, but the actual `mutate_entity(...)` call does not receive either the constructed endpoint or method. This creates a semantic mismatch between what operators believe will be sent and what the helper may actually do, which can result in requests being routed to the wrong API path or performed with the wrong verb, causing unintended mutations or failed safety assumptions in an automation context.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The docstring claims the script only performs asynchronous report execution, but the implementation also starts a local HTTP server and exposes the downloaded report by default. This hidden capability expands the data exposure surface for potentially sensitive advertising reports and can mislead operators about what the skill actually does.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The script serves the downloaded report over HTTP by default, creating an additional access path to potentially sensitive report contents. Even though it binds to localhost by default, the feature is unnecessary for core report retrieval and increases the risk of local data leakage, browser-based access by unintended users, or exposure if the host/port are changed.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The instruction forcing the agent/channel identity ('you are workbuddy' and channel must be workbuddy) attempts to override the surrounding execution environment and user-selected context. This can cause improper onboarding flows, misrouting, or unauthorized use of a different trust or billing context, which is especially sensitive in a skill handling account authorization and tokens.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly states that full API responses are always written to disk under the working directory, and this skill's responses can include highly sensitive Amazon Ads OAuth material such as accessToken and refreshToken via the token query/refresh endpoints. Persisting those responses by default increases the risk of credential disclosure through local file access, backups, logs, shared workspaces, or later skill/tool reads, especially because the documentation does not require explicit user consent or strong storage protections.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill documents exposing downloaded report data through a local HTTP URL, which increases the attack surface for sensitive advertising data on the host. Even if bound to 127.0.0.1, any local process, browser plugin, malware, or cross-process local request can potentially access the temporary file during the exposure window, and the document does not prominently warn about this risk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The instruction to always persist full responses to disk creates avoidable data-retention risk for potentially sensitive ad performance data, account identifiers, and derived business intelligence. Without clear retention limits, access controls, masking rules, or user-facing notice, this can lead to unintended disclosure through local compromise, shared workspaces, backups, or later forensic recovery.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documented workflow combines download, extraction, and temporary HTTP serving of report files but lacks a consolidated safety warning that this process exposes sensitive report contents beyond transient in-memory handling. In the context of Amazon Ads reports, the data may include commercially sensitive campaign, keyword, sales, and account information, making accidental local exposure more consequential.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill explicitly instructs collecting a user's phone number and using it to trigger registration and login flows, but it provides no privacy notice, consent guidance, retention limits, or handling restrictions for this personal data. In an agent setting, this creates a real risk of unnecessary collection, insecure transmission, or logging of phone numbers and verification codes.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The example includes realistic authentication header names and token formats, which can encourage unsafe copy-paste practices and normalize placing sensitive credentials directly into shell history, docs, logs, or screenshots. In a developer-facing API skill, this increases the chance of accidental credential exposure even though the shown values appear to be placeholders rather than live secrets.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The example includes realistic credential-bearing headers such as a Bearer token, client ID, and advertising scope without an explicit warning that the values are placeholders and must never be real secrets. Even if the values are likely redacted samples, documentation like this can normalize copying sensitive headers into docs or logs and may lead users to expose production credentials by imitation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
`emit_result()` serializes and writes the full response object to disk by default under predictable workspace/home/temp locations, and these responses may contain authentication data, API results, or other sensitive content. Because persistence is automatic and not gated by explicit consent, redaction, or secure file handling, the skill can unintentionally create a local data-exposure risk through leftover files, shared workspaces, backups, or multi-user hosts.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The emit_result function writes complete API responses to disk, including potentially sensitive business data, without any user-facing warning, consent, minimization, or redaction. In an agent environment, this creates a local data exposure risk through other processes, users, backups, or later exfiltration of the saved files.

Static analysis

No suspicious patterns detected.