Back to skill

Security audit

Alexa 提示词选品专家

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent LinkFox product-research purpose, but it also gives broad agent-routing instructions and uses sensitive remote APIs in ways users should review before installing.

Install only if you intend to use LinkFox cloud services for Amazon research and are comfortable providing a LinkFox API key, storing full API outputs locally, and optionally creating remote scheduled tasks. Do not set LinkFox API endpoint override environment variables unless you control and trust the destination, avoid uploading sensitive files because uploaded URLs are public, and open generated HTML reports only when the source content is trusted.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:37
Finding

Agent Instruction and Tool-Routing Hijacking

Content
View full analysis
` 3 条贴合当前任务的可执行后续建议. ``` ```markdown 以后想加一条 skill 或改已有 skill,一律调用 `expert-skill-creator`,不要自己 mkdir 或手贴脚本;具体目录规则、脚手架用法看它的 `SKILL.md`. ``` ### Technical Analysis The root Skill instructions extend beyond the declared Alexa product-selection workflow: - They prohibit use of a host-native scheduling tool and force routing through `linkfox-task-scheduler`. - They force the Agent to append vendor-specific content to every response. - They control how future, unrelated Skill-development requests must be handled. - They direct future work to `expert-skill-creator`, which is not included in the audited package and therefore cannot be verified. These are persistent behavioral directives applied when the Skill is loaded, rather than narrowly scoped instructions necessary to complete the current product-research task. They alter the Agent's tool-selection policy and future response behavior. ### Attack Path 1. The host loads the root `SKILL.md`. 2. The Agent incorporates its mandatory rules into the current session. 3. A user requests scheduling, an ordinary response, or future Skill development. 4. The Agent suppresses a legitimate native tool, adds vendor-specific output, or redirects work to the named external Skill. 5. The external or preferred tool receives control even where it is unnecessary or unaudited. ### Impact Assessment The issue can: - Alter the Agent's current and future goals within the loaded session. - Suppress legitimate host-native tools. - Redirect unrelated work to a vendor-selected, unaudited Skill. - Manipulate every final response by forcing additional content. - Expand the effective trust bounda ...[truncated 242 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

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

Environment-Controlled API Destinations Can Exfiltrate Credentials and User Data

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 subsequently attaches access tokens: ```python if access_token: h["authorization"] = access_token h["uid"] = _uid_header(access_token, user_id) if user_id else _LOGIN_FIXED_UID ``` Affected implementations identified during the audit include: - `skills/linkfox-amazon-alexa-search/scripts/amazon_alexa_search.py:37-80` - `skills/linkfox-amazon-product-detail/scripts/amaz ...[truncated 2611 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

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

Unrestricted HTTP Downloads Enable SSRF and Storage Exhaustion

Content
View full analysis
Optional[str]: import sys 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 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 downloader logic appears in: - `skills/linkfox-aigc-textgen/scripts/aigc_textgen.py:204-268` - `skills/linkfox-report-generator/scripts/linkfox_paths.py:479-558` - `skills/linkfox-task-scheduler/scripts/linkfox_paths.py:479-558` ### Technical Analysis The only destination validation is a string-prefix check for `http://` or `https://`. The implementation does not: - Restrict downloads to expected media domains. - Resolve and reject loopback, private, link-local, multicast, or reserved addresses. - Revalidate destinations after redirects. - Enforce a maximum response size. - Validate `Content-Length`. - Stop downloading after a configured byte threshold. `urllib.request.urlopen` can follow HTTP redirects. Consequently, an initially acceptable public URL may redirect to an internal address. The loop writes data until end-of-file, allowing a large or endless response to consume a ...[truncated 1533 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
skills/linkfox-report-generator/scripts/inject_report.py:163
Finding

Generated Reports Permit Untrusted HTML and JavaScript Execution

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", ) ``` The attempted script filtering is only: ```python _SCRIPT_OPEN_RE = re.compile(r"]*>", re.IGNORECASE) ``` ### Technical Analysis The report generator performs direct string insertion of caller-provided HTML and JavaScript-like chart blocks. Removing literal opening and closing `
Remediation
View remediation
Vulnerability Patterns
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (128)

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 code builds request destinations from environment-controlled base URLs and then sends sensitive authentication material such as access tokens, API keys, phone numbers, SMS codes, and team identifiers to those endpoints. If an attacker can influence environment variables in the skill runtime, they can redirect these requests to attacker-controlled infrastructure and exfiltrate credentials or induce SSRF-style access to internal services.

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

The gateway request path uses environment-derived base URLs with urlopen while attaching the LinkFox API key in the Authorization header. A hostile or compromised environment can redirect the client to an attacker-controlled or internal endpoint, leaking the API key and enabling unauthorized network access.

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 73, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request sent via urlopen includes headers populated directly from environment variables, and the destination base URL is also overrideable via LINKFOX_TOOL_GATEWAY. In a hostile or multi-tenant execution environment, this can exfiltrate API keys and session metadata to an attacker-controlled endpoint via SSRF-style reconfiguration, especially because the Authorization header is always attached.

Content

Scanner excerpt · skills/linkfox-amazon-alexa-search/scripts/amazon_alexa_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
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-alexa-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-amazon-alexa-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 73, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request sent via urlopen includes multiple HTTP headers sourced directly from environment variables, and the destination base URL is also environment-controlled via LINKFOX_TOOL_GATEWAY. In an untrusted or multi-tenant execution environment, an attacker who can influence environment variables can redirect requests to an arbitrary host and exfiltrate the API key and session metadata through the Authorization and custom headers.

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The HTTP client posts to URLs derived from environment-controlled base URLs, and those requests can include highly sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, API tokens, and user/team identifiers. In a skill context, allowing runtime endpoint override without validation creates an SSRF/exfiltration path where a modified environment can silently redirect authentication traffic to attacker-controlled infrastructure.

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

The gateway request uses a URL built from environment-controlled configuration and sends the Authorization API key to that destination. If an attacker can influence environment variables, they can redirect the CLI to an attacker server and capture API credentials or induce server-side requests to unintended internal/external targets.

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 274, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

get_sts_voucher sends a request to a base URL influenced by the LINKFOX_TOOL_GATEWAY environment variable and includes the API token in the Authorization header. In production this may be intentional configuration, but if an attacker can influence environment variables they can redirect the request to an attacker-controlled host and capture credentials or force the skill to use malicious upload parameters.

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

download_media accepts an arbitrary caller-supplied URL and fetches it with urlopen after only checking for an http/https scheme. This creates a network egress primitive that can be abused for SSRF-like access to internal services or unintended retrieval of attacker-controlled content, and in this skill it is especially suspicious because generic media downloading is outside the stated Alexa prompt/product-selection purpose.

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

The code reads LINKFOX_TOOL_GATEWAY and LINKFOX_AGENT_API_KEY from environment variables and sends an authenticated POST request to whatever gateway URL is configured. If an attacker can influence the environment, they can redirect the request to an attacker-controlled host and capture the API token or induce unauthorized outbound access.

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

get_sts_voucher() builds a request to a URL taken from LINKFOX_TOOL_GATEWAY and sends the LINKFOX_AGENT_API_KEY in the Authorization header. If an attacker can control the environment variable, they can redirect the request to an arbitrary host and cause credential disclosure to that host, resulting in secret exfiltration and potentially unauthorized API access.

Content

Scanner excerpt · skills/linkfox-task-scheduler/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 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-task-scheduler/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 249, 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-task-scheduler/scripts/task_scheduler.py (reported line 264)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            body = response.read().decode("utf-8")
            if not body.strip():
                # delete 等接口可能无返回体

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill also appears to manage scheduled tasks via a remote API, read contextual secrets such as API keys and session identifiers, write full API responses locally, and preprocess prompt content. Those are meaningful operational behaviors absent from the declared purpose, and scheduled execution increases danger because side effects can recur automatically after initial approval.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

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