Back to skill

Security audit

销量飙升榜专家

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Amazon product-scouting skill, but it bundles high-impact helper code that can persistently alter agent instructions and can send API credentials to environment-configured endpoints.

Review before installing. Only use this if you trust the LinkFox service and publisher, keep LINKFOX_TOOL_GATEWAY unset or pinned to the official HTTPS gateway, treat LINKFOX_AGENT_API_KEY as a secret, and do not run patch_scoring_to_agent.py or its --all mode unless you intentionally want to rewrite persistent agent instruction files. Also remember uploads create public URLs and scheduled scouting can repeatedly consume credits.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T02 · Agent Memory Poisoning

Error
Location
skills/amazon-asin-dynamic-scoring/scripts/patch_scoring_to_agent.py:143
Finding

Persistent modification of agent instruction files across workspaces

Content
View full analysis
bool: """Patch a CLAUDE.md file to add scoring module. Returns True if changes made.""" path = Path(filepath) if not path.exists(): print(f"ERROR: File not found: {filepath}") return False content = path.read_text(encoding="utf-8") # Check if already has the full scoring step (not just the reference line) if "二次评分(动态评分引擎)" in content: print(f"SKIP: {filepath} already has scoring step") return False # Check if it uses amazon-product-scout-agent if "amazon-product-scout-agent" not in content: print(f"SKIP: {filepath} does not use amazon-product-scout-agent") return False original = content changes = [] # Additional workflow instructions are inserted into content here. if content == original: print(f"NO CHANGE: {filepath} (patterns not matched, may need manual edit)") return False path.write_text(content, encoding="utf-8") print(f"PATCHED: {filepath}") print(f" Changes: {', '.join(changes)}") return True def main(): if len(sys.argv) < 2: print("Usage: python3 patch_scoring_to_agent.py [ ...]") print(" python3 patch_scoring_to_agent.py --all (auto-find all agents)") sys.exit(1) if sys.argv[1] == "--all": # Auto-find all CLAUDE.md files in agents directory agents_dir = Path("/root/.linkfox/workspaces/agents") targets = sorted(agents_dir.glob("*/CLAUDE.md")) # Also check workspace root root_claude = Path("/root/.linkfox/workspaces/CLAUDE.md") if root_claude.exists(): targets.append(root_claude) else: targets ...[truncated 2165 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-file-upload/scripts/linkfox_paths.py:227
Finding

API credentials can be transmitted to an unvalidated gateway endpoint

Content
View full analysis
str: """tool-gateway base address: LINKFOX_TOOL_GATEWAY takes precedence.""" return ( os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com" ).rstrip("/") def get_sts_voucher() -> dict: import sys import urllib.error from urllib.request import urlopen, Request base = _get_agent_base() api_token = os.environ.get("LINKFOX_AGENT_API_KEY") or "" url = f"{base}/oss/getStsVoucherByAPI" last_exc: Exception = RuntimeError("Unknown error") body: dict = {} for attempt in range(3): if attempt: time.sleep(1 << (attempt - 1)) req = Request( url, method="POST", data=b"{}", headers={ "Content-Type": "application/json", "Authorization": api_token, }, ) try: with urlopen(req, timeout=30) as resp: body = json.loads(resp.read().decode()) break ``` The scheduler uses the same trust pattern: ```python def call_api(action, params): api_key = get_api_key() url = base_url() + ACTIONS[action] data = json.dumps(params).encode("utf-8 ...[truncated 2634 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-aigc-textgen/scripts/onboarding.py:468
Finding

Generated API key is emitted in plaintext through standard output

Content
View full analysis
dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return { "error": f"login: invalid phone format: {phone}", "phone": masked, } if not re.fullmatch(r"\d{4,8}", code): return { "error": f"login: invalid verification code format: {code}", "phone": masked, } lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} if lg.get("is_new_user"): lbt = _login_by_token(lg["access_token"], lg["refresh_token"]) if "error" in lbt: print(f"{TAG} {lbt['error']}", file=sys.stderr) info = _fetch_user_info_v3(lg["access_token"], lg["user_id"]) if "error" in info: return {"error": info["error"], "phone": masked} tok = _get_or_generate_api_token( lg["access_token"], lg["user_id"], info["group_id"], ) if "error" in tok: return {"error": tok["error"], "phone": masked} return { "api_key": tok["api_key"], "phone": masked, "group_id": info["group_id"], "member_id": info["member_id"], "source": tok["source"], "nick_name": lg.get("nick_name", ""), "team_name": info.get("team_name", ""), "is_new_user": lg.get("is_new_user", False), } def _emit(obj: dict) -> None: print(json.dumps(obj, ensure_ascii=False, indent=2)) def _cmd_login(args) -> int: r = login_and_get_key( args. ...[truncated 2054 chars]
Remediation
View remediation

T08 · Insecure Dependencies

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

Third-party packages are installed without pinned versions or integrity verification

Content
View full analysis
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 (148)

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

Critical
Category
Data Flow
Confidence
93% confidence
Finding

download_media performs outbound requests to arbitrary caller-supplied URLs using urlopen and only checks for http/https. This creates an SSRF-capable primitive that can reach internal services, cloud metadata endpoints, or other sensitive network locations and then persist the response locally, increasing the chance of data exposure.

Content

Scanner excerpt · skills/amazon-product-scout-agent/scripts/linkfox_paths.py (reported line 504)May include surrounding context.

python
req = Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
    try:
        with urlopen(req, timeout=timeout) as resp:
            # 从 Content-Type 进一步修正扩展名
            if guessed_ext == "bin":
                ct = resp.headers.get("Content-Type", "")

Tainted flow: '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
94% 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 API-token requests to those endpoints. In a hostile or multi-tenant runtime, an attacker who can influence environment variables can redirect these authenticated requests to attacker-controlled servers and exfiltrate credentials.

Content

Scanner excerpt · skills/linkfox-aigc-textgen/scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The gateway URL is also derived from environment variables and then used by urllib.request.urlopen with the Authorization header populated from LINKFOX_AGENT_API_KEY. This enables exfiltration of the API key and account/order metadata to attacker-controlled infrastructure if the environment is manipulated.

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

download_media() performs arbitrary outbound HTTP(S) requests to attacker-controlled URLs and writes the response to disk. Although it rejects non-HTTP schemes, it still enables SSRF-style access to internal services or unexpected data retrieval if untrusted input reaches url, which is especially risky because this capability is unrelated to the stated product-scouting/Excel-delivery 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
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: '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 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, this becomes credential exfiltration and SSRF to attacker-controlled infrastructure.

Content

Scanner excerpt · skills/linkfox-sellersprite-product-search/scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The gateway request path uses an environment-derived base URL and transmits the bearer API key in the Authorization header via urlopen. A malicious or poisoned runtime environment could redirect requests to an attacker-controlled host, leaking the API key and enabling unauthorized account actions or internal network access attempts.

Content

Scanner excerpt · skills/linkfox-sellersprite-product-search/scripts/onboarding.py (reported line 246)May include surrounding context.

python
headers["Content-Type"] = "application/json"
        req = Request(url, method=method, data=body_bytes, headers=headers)
        try:
            with urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            status = e.code

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request includes multiple headers sourced directly from environment variables, and the destination URL is also overrideable via LINKFOX_TOOL_GATEWAY. In this skill context, that creates a real exfiltration risk: secrets and session metadata can be sent to an attacker-controlled endpoint if the environment is poisoned or misconfigured, especially because the Authorization API key is always attached to the outbound request.

Content

Scanner excerpt · skills/linkfox-sellersprite-product-search/scripts/sellersprite_product_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: '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/amazon-product-scout-agent/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-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

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 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 outbound requests to arbitrary user-supplied URLs and then writes the response to disk. Although it restricts schemes to HTTP/HTTPS, it still enables SSRF-style access to internal services or unintended remote content retrieval, which is outside the stated Excel-only product-scouting scope and increases abuse potential.

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 includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes direct integration with linkfox-task-scheduler for recurring automation and states that scheduled tasks can be created after collecting parameters and cost confirmation. Recurring execution increases blast radius because a misconfigured or abused workflow can repeatedly trigger networked operations, file writes, or downstream skills over time, especially when combined with broad undeclared tool capabilities.

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