Back to skill

Security audit

未满足需求挖掘专家

Security checks for vulnerabilities and agentic risk

Overview

The skill largely performs Amazon product scouting as described, but it bundles under-disclosed high-impact helpers that can persistently alter agent instructions, run environment-selected scripts, and send credentials through environment-selected endpoints.

Install only in a controlled environment where you trust the publisher and can lock LinkFox endpoint environment variables to the intended HTTPS domains. Review or remove the CLAUDE.md patch script and arbitrary script-runner paths before use, confirm any scheduled task and its credit cost, avoid uploading private files to public URLs, and pin dependencies before installing them.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (5)

T02 · Agent Memory Poisoning

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

Persistent modification of Agent instruction files

Content
View full analysis
[ ...]") print(" python3 patch_scoring_to_agent.py --all (auto-find all agents)") sys.exit(1) if sys.argv[1] == "--all": agents_dir = Path("/root/.linkfox/workspaces/agents") targets = sorted(agents_dir.glob("*/CLAUDE.md")) root_claude = Path("/root/.linkfox/workspaces/CLAUDE.md") if root_claude.exists(): targets.append(root_claude) else: targets = [Path(p) for p in sys.argv[1:]] ``` The content written by `patch_file()` adds new trigger phrases, Skill references, workflow steps, output requirements, and recommendations to the selected Agent instruction file. ### Technical Analysis The utility persistently rewrites `CLAUDE.md`, which is an Agent instruction and behavior configuration file. Its `--all` option enumerates every Agent configuration under `/root/.linkfox/workspaces/agents` and also targets the workspace-level configuration. This behavior is outside the minimum privileges needed to score ASIN data. The normal scoring operation only needs to read product data, calculate scores, and write result files. It does not need to modify the long-term instructions of the current Agent or unrelated Agents. Because the inserted instructions persist after the process ends, future sessions can continue to follow the injected rules. Although the bundled injected text is related to scoring, the mechanism itself is a persistent instruction-writing channel and could be altered or invoke ...[truncated 1178 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
skills/amazon-product-scout-agent/scripts/product_scout_agent.py:80
Finding

Environment variable permits replacement of the trusted SellerSprite client with arbitrary Python code

Content
View full analysis
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
skills/amazon-product-scout-agent/scripts/response_io.py:66
Finding

Generic script runner executes arbitrary local Python with the full inherited environment

Content
View full analysis
Path: p = Path(script_arg).expanduser() if not p.is_absolute(): p = (Path.cwd() / p).resolve() else: p = p.resolve() if not p.is_file(): _err(f"--script path not found: {p}") return p ``` ```python def cmd_run(args: argparse.Namespace) -> int: main_script = _resolve_script(args.script) skill_name = _resolve_skill_name(main_script) params_str = _resolve_params(args) out_dir = Path(args.out_dir).expanduser().resolve() try: out_dir.mkdir(parents=True, exist_ok=True) except OSError as e: _err(f"Failed to create --out-dir {out_dir}: {e}") if not os.access(out_dir, os.W_OK): _err(f"--out-dir is not writable: {out_dir}") child_env = os.environ.copy() child_env["PYTHONIOENCODING"] = "utf-8" proc = subprocess.run( [sys.executable, str(main_script), params_str], capture_output=True, text=True, encoding="utf-8", errors="replace", env=child_env, timeout=args.timeout, ) ``` ### Technical Analysis The runner accepts any path supplied through `--script`. `_resolve_script()` verifies only that the resolved path points to a file. It does not require the file to belong to the project, reside in a trusted `scripts` directory, have trusted ownership, or match an expected hash. The runner then copies the complete process environment and executes the selected file using Python. This exposes every inherited environment variable to the selected script, including any API keys or session-related values present in the Agent runtime. This generic execution capability exceeds the requirements of response formatting and output management. A res ...[truncated 1277 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-task-scheduler/scripts/linkfox_paths.py:45
Finding

Unvalidated API endpoint overrides can redirect credentials and private request data

Content
View full analysis
str: """Gateway base address: environment override with a production fallback.""" return ( os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com" ).rstrip("/") ``` ```python def call_api(action, params): api_key = get_api_key() url = base_url() + ACTIONS[action] data = json.dumps(params).encode("utf-8") req = Request( url, data=data, headers={ "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/2.0", "SESSION_ID": os.environ.get("SESSION_ID", ""), "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), }, method="POST", ) try: with urlopen(req, timeout=150) as response: body = response.read().decode("utf-8") ``` Equivalent unvalidated endpoint behavior is also present in: - `skills/linkfox-file-upload/scripts/linkfox_paths.py` - `skills/linkfox-report-generator/scripts/linkfox_paths.py` - `skills/amazon-product-scout-agent/scripts/linkfox_paths.py` - `skills/linkfox-aigc-textgen/scripts/aigc_textgen.py` - `skills/linkfox-sellersprite-product-search/scripts/sellersprite_product_search.py` - Both onboarding scripts, which additionally accept `LINKFOX_AGENT_API_URL`, `LINKFOX_LOGIN_API_URL`, and `LINKFOX_AGENT_USER_API_URL` ### Technical Analysis The code permits environment variables to replace trusted LinkFox service endpoints without validating: - The URL scheme. - The destination h ...[truncated 2304 chars]
Remediation
View remediation

T08 · Insecure Dependencies

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

Runtime installation guidance uses unpinned third-party dependencies

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 (143)

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 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 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 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 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 POST target is derived from environment-controlled base URLs and is used to send sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys. If an attacker can influence environment variables, they can redirect these requests to attacker-controlled endpoints and exfiltrate credentials or payment-related data. The skill context increases severity because this file handles onboarding and token issuance rather than the stated unmet-demand analysis purpose, so the networked secret flow is unjustified and higher risk.

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

The gateway URL is constructed from environment-controlled base values and then used with an Authorization header containing the API key. An attacker who can set the environment can redirect authenticated gateway traffic to a malicious server and capture API credentials, user/account data, or manipulate commerce operations such as plan lookup and order creation. The mismatch between skill purpose and this onboarding/payment behavior makes this more dangerous because users would not expect credentialed payment flows in this skill.

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

download_media() fetches an attacker-controlled URL with urlopen() and only restricts the scheme to HTTP/HTTPS. This enables SSRF against internal services, metadata endpoints, or other network-reachable resources, and the downloaded content is then written into the session workspace, increasing abuse potential.

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

The script builds request destinations from environment variables such as LINKFOX_LOGIN_API_URL and LINKFOX_AGENT_USER_API_URL, then sends sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those endpoints. If an attacker can influence the environment, they can redirect authentication and token traffic to an attacker-controlled server, causing credential exfiltration and account compromise.

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

The gateway URL is derived from environment-controlled base URLs and used in urllib requests with the Authorization header set to the LinkFox API key. An attacker who can tamper with the environment can redirect these requests to a malicious endpoint and harvest the API key or manipulate billing, order, and account queries.

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

The download_media function performs outbound requests to an arbitrary caller-supplied URL with only a scheme check for http/https. This enables SSRF-style behavior, allowing access to internal services, cloud metadata endpoints, or other network-reachable resources, and the downloaded content is then written to disk and registered in session metadata. In the context of an unmet-demand mining skill, this network-fetch capability is broader than necessary and therefore more suspicious.

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

The request sent via urlopen includes multiple headers populated directly from environment variables, including SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME. Because the destination base URL is also indirectly configurable via helper logic and the code performs no allowlist or minimization of forwarded metadata, this creates a real data-exfiltration risk: sensitive runtime/session context can be transmitted to a remote service or a misconfigured endpoint without validation.

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 declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared scope is unmet-demand analysis, but the reported behavior also creates, updates, deletes, and queries scheduled tasks through an external scheduling gateway while writing API responses locally. Scheduler control is a privileged automation capability that can create persistence and repeated external actions, making the mismatch especially dangerous in a skill users would expect to be a one-off analysis tool.

Content

No source excerpt is available for this finding.