Back to skill

Security audit

亚马逊-店铺Fulfillment Outbound

Security checks for vulnerabilities and agentic risk

Overview

The advertised Amazon fulfillment skill mostly matches its main wrappers, but the package also contains hidden account-login, API-key generation, and payment-order tooling that is outside that purpose.

Review this skill before installing. The Amazon fulfillment wrappers include useful safeguards, but the package also ships unrelated LinkFox login, API-key, and payment-order code, and it stores full fulfillment responses locally. Install only if you trust the publisher, understand where credentials and customer/order data are sent and stored, and are comfortable with the extra account and billing capabilities being present in the package.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/onboarding.py:402
Finding

Undeclared authentication, credential forwarding, and billing capabilities exceed the Skill's required privileges

Content
View full analysis
dict: """New-user credit activation. Failure does not block the flow.""" resp = _http_post(f"{_agent_user_base()}/account/loginByToken", { "token": access_token, "refreshToken": refresh_token, "device": {"aid": "3026344186", "did": "", "type": "Windows", "os": "10", "model": "149.0.0.0", "brand": "Chrome"}, }, _headers("agent-linkfox-web", "agent.linkfox.com", access_token=access_token)) if "_error" in resp: return {"error": f"loginByToken: {resp.get('_body') or resp['_error']}"} if resp.get("errcode") != 200: return {"error": f"loginByToken: {resp.get('errmsg') or json.dumps(resp, ensure_ascii=False)}"} print(f"{TAG} loginByToken succeeded and new-user credits were activated", file=sys.stderr) return {} def _fetch_user_info_v3(access_token: str, user_id: str) -> dict: """Obtain group_id and member_id from userInfo.""" resp = _http_post(f"{_login_base()}/linkFoxApp/api/userCenter/userInfo", {}, _headers("agent-linkfox-web", "agent.linkfox.com", access_token=access_token, user_id=user_id)) if "_error" in resp: return {"error": f"userInfo: {resp.get('_body') or resp['_error']}"} if resp.get("code") != "OK": return {"error": f"userInfo: {resp.get('message') or json.dumps(resp, ensure_ascii=False)}"} teams = (resp.get("data") or {}).get("teamList") or [] if not teams: return {"error": "userInfo: no team workspace is enabled"} selected = (next((t for t in teams if t.get("isSelect") == 1 and t.get("agentTeamId")), None) or next((t for t in teams if t.get("agentTeamId")), None)) ...[truncated 4312 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:491
Finding

Generated API key is returned and printed in plaintext

Content
View full analysis
None: print(json.dumps(obj, ensure_ascii=False, indent=2)) def _cmd_login(args) -> int: r = login_and_get_key(args.phone.strip(), args.code.strip(), args.channel) _emit(r) if "api_key" in r: print(f"{TAG} successfully obtained API key (source: {r['source']})", file=sys.stderr) return 0 return 1 ``` The status text is translated into English for report readability; the credential-return and output behavior is unchanged. ### Technical Analysis `login_and_get_key` places the complete reusable API key in a result dictionary. `_cmd_login` then passes that dictionary to `_emit`, which serializes and prints the complete object to stdout. Standard output is commonly retained by agent tool-call transcripts, terminal scrollback, CI logs, process supervisors, shell redirection, and observability systems. The project does not redact or mask the key before output. Several error paths also serialize complete upstream responses, creating an additional risk if a service includes credentials in an error response. This violates the principle that reusable credentials should only be transferred through protected secret-storage channels. ### Attack Path 1. A user invokes `python scripts/onboarding.py login `. 2. The script obtains or generates an API key. 3. The complete key is inserted into the returned dictionary. 4. `_emit` prints the dictionary as JSON to stdout. 5. An agent transcript ...[truncated 497 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_linkfox_gateway.py:35
Finding

Environment-controlled network destination can receive API credentials without HTTPS or host validation

Content
View full analysis
str: """Gateway base address: LINKFOX_TOOL_GATEWAY takes precedence.""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") def get_api_url(): sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "_shared")) return get_api_base() + API_PATH def get_api_key(): key = os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get("LINKFOXAGENT_API_KEY") if not key: print( "API Key not configured. Please complete authorization first:\n" "1. Visit https://skill.linkfox.com/linkfoxskills/guide.htm to obtain your Key\n" "2. Set the environment variable: export LINKFOX_AGENT_API_KEY=your-key-here", file=sys.stderr, ) sys.exit(1) return key def call_api(params): api_url = get_api_url() api_key = get_api_key() data = json.dumps(params).encode("utf-8") 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", ""), } req = Request( api_url, data=data, headers=headers, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` The function docstring is translated into English for report readability; the destination-selection and credential-transmission behavior is unchanged. ### Technical Analysis `LINKFOX_TOOL_GA ...[truncated 1871 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_spapi_fulfillment_outbound_common.py:637
Finding

Complete fulfillment responses and customer data are cached and persisted in plaintext

Content
View full analysis
Any | None: if not os.path.isfile(path) or time.time() - os.path.getmtime(path) > 24 * 60 * 60: return None try: with open(path, encoding="utf-8") as handle: return json.load(handle) except (OSError, json.JSONDecodeError): return None def _lf_save_cache(path: str, payload: Any) -> None: try: with open(path, "w", encoding="utf-8") as handle: json.dump(payload, handle, ensure_ascii=False, indent=2) except OSError: pass ``` ```python def emit_result(result: Any, slug: str = SLUG, inline: bool = False) -> None: """Persist the complete response, printing full JSON only when reasonably small.""" serialized = json.dumps(result, ensure_ascii=False, indent=2) timestamp = time.time() date_text = time.strftime("%Y-%m-%d", time.localtime(timestamp)) session_id = _lf_session_id(timestamp) root = _lf_root() session_dir = os.path.join(root, date_text, session_id) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_text, session_id, timestamp) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) output_path = os.path.join(data_dir, f"{slug}-{int(timestamp * 1_000_000)}.json") try: with open(output_path, "w", encoding="utf-8") as handle: handle.write(serialized) print(f"Saved full response: {output_path} ({len(serialized)} bytes)") _lf_update_meta(session_dir, output_path, timestamp) except OSError as exc: print(f"Failed to save to {output_path}: {exc}", file=sys.stderr) raise SystemExit(1) from exc ``` ### Technical Analysis The active operation ru ...[truncated 1832 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (31)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request sent to urlopen includes multiple headers populated directly from environment variables, and the destination base URL is also overridable via LINKFOX_TOOL_GATEWAY. That creates a real exfiltration/SSRF-style risk: secrets and session identifiers can be transmitted to an attacker-controlled endpoint if the environment is manipulated, which is especially sensitive in a gateway module handling API credentials and fulfillment data.

Content

Scanner excerpt · scripts/_linkfox_gateway.py (reported line 76)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""

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

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The HTTP destination is derived from environment-controlled base URLs and then used in requests.post with sensitive payloads and headers, including login tokens and API-key related material. In a skill context, environment variables are part of the deployment trust boundary; if they are misconfigured or attacker-influenced, the script can exfiltrate credentials, SMS login data, and account metadata to an attacker-controlled endpoint.

Content

Scanner excerpt · scripts/onboarding.py (reported line 196)May include surrounding context.

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

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

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The gateway URL is built from environment variables and then passed to urllib.request.urlopen with the Authorization header populated from the LinkFox API key. If an attacker can influence the runtime environment, they can redirect authenticated gateway traffic to a malicious server and capture API keys and order/account data.

Content

Scanner excerpt · 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

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill advertised as Amazon fulfillment management can instead drive SMS login, API-key retrieval, user/team queries, plan listing, and payment order creation, it crosses into credential, account, and billing workflows far outside the stated scope. That kind of hidden capability expansion is dangerous because it can induce collection of verification codes, create charges, or expose account metadata under the pretense of a logistics task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill advertised as Amazon fulfillment management can instead drive SMS login, API-key retrieval, user/team queries, plan listing, and payment order creation, it crosses into credential, account, and billing workflows far outside the stated scope. That kind of hidden capability expansion is dangerous because it can induce collection of verification codes, create charges, or expose account metadata under the pretense of a logistics task.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 68)May include surrounding context.

md
- Amazon's Outbound overview role list mentions `getInvoiceHeaders`, but its Reference path is `/finances/invoices/2026-06-25/invoices`. This Skill exposes it as an explicitly labeled related Invoices operation; it is not counted among the nine Outbound OpenAPI operations and does not accept `fulfillmentServiceId`.
- Legacy v2020-07-01 returns, features, and package-tracking operations remain in the production FBA Skill and are not copied into this current-version Skill. Read [references/migration.md](references/migration.md) when migrating.

## Display Rules

- Present Amazon data and identifiers without exposing internal tool names or access tokens.
- Separate operation success from business completion: show gateway `errcode`, Amazon `httpStatus`, order `status`, constraints, and next action.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 70)May include surrounding context.

md
## Display Rules

- Present Amazon data and identifiers without exposing internal tool names or access tokens.
- Separate operation success from business completion: show gateway `errcode`, Amazon `httpStatus`, order `status`, constraints, and next action.
- For offers and previews, show expiration, service tier, delivery interval, currency, price, and item constraints together.
- For orders, show `orderId`, status, line items, shipments, packages, tracking, proof of delivery, drop-off/locker details, unit identifiers, and pagination token only when present.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file implements LinkFox account onboarding, SMS login, package purchasing, and payment flows rather than any Amazon MCF outbound fulfillment capability described by the skill metadata. This severe mismatch indicates the skill can trigger unrelated credential collection and commercial actions under false pretenses, which is especially dangerous because users would expect Amazon fulfillment operations, not third-party account/payment onboarding.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code lists purchasable plans, creates orders, and renders payment QR codes for LinkFox subscriptions, which is unrelated to Amazon MCF order fulfillment. In this skill context, embedding payment collection behavior behind a mismatched Amazon-themed description materially increases the risk of deceptive billing or social engineering.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code sends SMS verification codes, logs into a third-party LinkFox account, and retrieves or generates API tokens, all unrelated to Amazon MCF. In the context of a mislabeled skill, that is effectively credential acquisition and token issuance capability hidden behind an unrelated business description, creating strong risk of account compromise and unauthorized API access.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes capabilities that involve shell, filesystem, environment, and network access, but it does not declare an explicit tool scope or permission boundary. That creates an authorization gap where an agent may invoke broader capabilities than a reviewer or user would expect, increasing the chance of unintended command execution, local file access, or outbound requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger language is broad enough to activate on generic fulfillment-related requests, which raises the risk of this skill being selected when the user did not intend Amazon MCF specifically. In context, that matters more because the skill already appears to have behavior/scope ambiguities, so over-triggering increases exposure to the wrong tools and data flows.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to always persist full API responses to session files and sometimes print full JSON to stdout. In this skill's context, those responses may contain recipient details, tracking numbers, proof-of-delivery data, locker/drop-off details, and other sensitive fulfillment information, creating a clear data leakage and over-retention risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api.md (reported line 139)May include surrounding context.

判定顺序:先检查 errcode == 200,再检查 Amazon httpStatus,最后读取解析结果。400/403/404/413/415 修正请求;429/500/503 或超时不自动重放写操作。

curl 示例

bash
curl --request POST "${LINKFOX_TOOL_GATEWAY}/spApi/developerProxy" \

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring labels the output policy and all behavioral instructions in Chinese, indicating a fixed language/locale expectation in the skill's natural-language guidance. The file does not offer a user language choice or explain a justified region-specific requirement, which fits the locale-policy violation criteria.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module is designed to persist full API responses, cache payloads, and maintain per-session metadata on local disk. In the context of Amazon MCF outbound fulfillment, responses can contain customer shipping details, tracking information, signatures, locker/drop-off details, and invoice headers, so broad default persistence expands data exposure beyond the stated API-call purpose.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The implementation contradicts its own storage policy by falling back to home and temporary directories when the current directory is not writable, despite the docstring stating /tmp is forbidden and failure should occur instead. This kind of silent policy bypass can cause sensitive fulfillment data to be written into less controlled locations, increasing accidental disclosure risk and undermining operator expectations.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/_spapi_fulfillment_outbound_common.py (reported line 69)May include surrounding context.

python
print(f"DEPENDENCY_MISSING: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
        raise SystemExit(DEPENDENCY_EXIT_CODE)
    try:
        result = subprocess.run(
            [sys.executable, str(checker)],
            capture_output=True,
            text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Successful operation outputs are cached to disk silently for up to 24 hours, again without user-facing disclosure or consent. In the context of fulfillment outbound operations, cached responses may contain sensitive order, shipment, or recipient information, so this creates avoidable local data-at-rest exposure and may conflict with least-retention expectations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill persistently writes full API responses, cache entries, and session metadata to local disk under the linkfox directory, including data returned from fulfillment outbound APIs. In this skill context, responses can contain sensitive business and customer information such as order details, tracking, proof-of-delivery, recipient, and locker/drop-off data, so unnecessary retention increases exposure to local compromise, later unintended access, and data handling violations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function saves the complete serialized API result to disk automatically, without any explicit warning, consent, or confirmation. Given this skill handles Amazon MCF outbound data that may include customer delivery and proof-of-delivery information, silent persistence is dangerous because users may reasonably expect an API wrapper to return data transiently rather than create durable local copies.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill manifest scopes this capability to Fulfillment Outbound / MCF order-management workflows, but the registry also exposes getInvoiceHeaders against the Finances API. That expands the skill's reachable data surface beyond the advertised domain and could let users or upstream orchestration retrieve financial invoice metadata that operators did not intend to grant through this skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language interface, help text, and validation logic are all fixed to Chinese usage, including domestic 11-digit phone numbers and area code +86. This enforces a specific language/locale behavior without offering user choice or documenting an explicit opt-in or region-scoped justification within the file.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · 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 = ""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The function obtains or generates an API token and returns it directly without any in-band warning, minimization, or explicit confirmation step. In a deceptive or repurposed skill context, exposing freshly generated credentials increases the chance of accidental leakage through logs, chat transcripts, or downstream tooling.

Content

No source excerpt is available for this finding.