Back to skill

Security audit

亚马逊-店铺Fulfillment Inbound

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches an Amazon FBA inbound workflow, but it needs review because it handles account credentials, payment flows, configurable network destinations, and persistent seller data in ways that are not tightly scoped.

Install only if you trust LinkFox with your Amazon seller fulfillment data and LinkFox account billing flow. Avoid setting gateway URL override environment variables unless you control the destination, do not paste API keys into shared logs or shell history, prefer a secret manager over shell profile storage, and keep the generated linkfox output directory out of shared or synced workspaces.

Vulnerability Patterns
  • 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
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_linkfox_gateway.py:34
Finding

Environment-Controlled Network Endpoints Can Receive Credentials and Seller Data

Content
View full analysis
str: """Gateway base address: LINKFOX_TOOL_GATEWAY takes priority.""" return ( os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com" ).rstrip("/") ``` ```python 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 onboarding endpoints are similarly configurable: ```python def _agent_base() -> str: return _env_base( "LINKFOX_AGENT_API_URL", "https://tool-gateway.linkfox.com", "LINKFOX_TOOL_GATEWAY", ) def _login_base() -> 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", ) ``` ```python def _http_post(url: str, body: dict, headers: dict, timeout: int = 30) -> dict: try: _require_requests() except RuntimeError as e: return {"_error": str(e)} try: r = requests.post( url, json=body or {}, headers= ...[truncated 2149 chars]
Remediation
View remediation

other

Warning
Location
scripts/_linkfox_gateway.py:56
Finding

Gateway Requests Transmit Agent Session Metadata Beyond the Fulfillment Operation Requirements

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:468
Finding

Onboarding Exposes Generated API Keys Through Standard Output and Plaintext Shell Profiles

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), } ``` ```python 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.phone.strip(), args.code.strip(), args.channel) _emit(r) if "api_key" in r: print( f"{TAG} Successfully obtained API key", file=sys.stderr, ) return 0 return 1 ` ...[truncated 1874 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_spapi_fulfillment_inbound_common.py:591
Finding

Complete Fulfillment Requests and Responses Are Persisted Without Restrictive File Permissions

Content
View full analysis
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) ``` The stored result explicitly includes submitted request bodies: ```python result: dict[str, Any] = { "operationId": operation_id, "method": spec["method"], "resolvedPath": path, "developerProxy": proxy, } if query_string: result["queryString"] = query_string if body_obj is not None: result["requestBody"] = body_obj ``` ### Technical Analysis The Skill intentionally writes complete operation resul ...[truncated 1671 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:162
Finding

Onboarding Recommends Installing Unpinned Runtime Dependencies

Content
View full analysis
dict: try: import qrcode except ImportError: err = ( "Missing qrcode dependency; run: " "pip install qrcode pillow" ) print(f"{TAG} render_qr: {err}", file=sys.stderr) return { "png_path": None, "ascii_qr": None, "error": err, } ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError( "Missing requests dependency; run: pip install requests" ) ``` ### Technical Analysis The runtime instructs users to install `qrcode`, `pillow`, and `requests` without exact versions, hashes, a lockfile, a trusted package index, or an isolated environment. The named packages are recognizable and there is no evidence that the project intentionally references a malicious package. Nevertheless, unpinned installation means the code executed in the future may differ from the code reviewed during this audit. Package-index compromise, dependency compromise, unexpected major-version changes, or index substitution can introduce arbitrary Python code under the privileges of the installing user. ### Attack Path 1. The user runs onboarding in an environment where one of the imports is unavailable. 2. The script displays an unpinned `pip install` instruction. 3. The user executes the instruction against the environment's configured package index. 4. A compromised, substituted, or incompatible future package version is downloaded. 5. Installation hooks or imported package code executes with the user's privileges. ### Impact Assessment A compromised dependency can execute arbitrary code with the privileges of the Python environment. It may read API keys, shell pr ...[truncated 233 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (32)

Tainted flow: 'req' from os.environ.get (line 69, 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 · 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 POST destination is derived from environment-controlled base URLs, and this code sends sensitive authentication material such as SMS login data, access tokens, refresh tokens, and generated API tokens to those endpoints. If an attacker can influence environment variables, they can redirect these requests to attacker-controlled infrastructure and exfiltrate credentials or payment/session data; in a skill context, this is especially dangerous because the file's purpose is onboarding and key issuance.

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

The gateway request target is built from environment-derived base URLs and used with an Authorization header carrying the API key. An attacker who can set or influence the environment can redirect gateway traffic to a rogue server, capturing API keys and order/account data; this is amplified by the skill's ability to create orders and interact with account state.

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

声明描述的是一个面向亚马逊 FBA 入仓流程的业务技能,应能处理 createInboundPlan、packing/placement/transportation options、箱唛标签、预约等。提供的代码片段没有实现这些能力;它只扫描若干本地目录和环境变量,寻找依赖技能 linkfox-amazon-store-auth 的 SKILL.md 文件,并输出依赖检查结果。这属于辅助安装/运行时检查,而不是所声明的核心业务能力。虽然依赖检查可视为支持性实现细节,但当前代码片段的主功能与声明的主目的明显不同,因此应判定为描述与实际行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述聚焦于 Amazon FBA/Fulfillment Inbound 业务流程,但代码中没有任何亚马逊 SP-API、FBA 入仓计划、shipment、packing/placement/transportation option、标签或预约相关逻辑。相反,代码完全围绕 LinkFox 平台账户 onboarding 和商业购买流程展开,包含短信验证码登录、团队信息获取、API token 获取、套餐查询、下单支付和订单状态查询。这不仅是主用途完全不同,而且还执行了与声明无关的账号与支付能力,因此属于明显的描述与行为不一致。

Content

No source excerpt is available for this finding.

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 · references/onboarding.md (reported line 6)May include surrounding context.

md
## 业务前置条件

- 已安装并完成 `linkfox-amazon-store-auth` 的店铺授权。
- 调用时使用已授权店铺的 `sellerId` 和 `region`;不传入 raw access token。
- Amazon 应用和卖家授权包含 `Amazon Fulfillment` role。
- 创建入库计划前,MSKU 已在目标 marketplace 创建且符合 FBA 入库条件。涉及创建/检查 listing 时还需 Product Listing 权限。

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/onboarding.md (reported line 28)May include surrounding context.

md
手机号流程。
3. 手机号流程:
   - `python scripts/onboarding.py send-code <phone>`
   - 获取验证码后运行 `python scripts/onboarding.py login <phone> <code>`
4. 配置返回的 `api_key`并重启会话:
   - Windows PowerShell:`setx LINKFOX_AGENT_API_KEY "<key>"`
   - macOS zsh:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.zshrc && source ~/.zshrc`
   - Linux bash:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.bashrc && source ~/.bashrc`

## LinkFox billing 场景

`errcode=402` 或消息包含 `算力`、`余额`、`quota`、`insufficient`、`充值`、`套餐到期` 时:

1. `python scripts/onboarding.py list-plans`
2. 校验 `plan_id` 属于返回清单,支付方式属于该套餐 `available_methods`。
3. `python scripts/onboarding.py order <plan_id> <method>`
4. 展示优先级:PNG 二维码 > `pay_url` > `ascii_qr`。
5. 用户确认付款后可调用 `python scripts/onboarding.py query <order_id>`;不主动轮询。

`errcode=403` 通�

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements LinkFox account onboarding, SMS login, API-key acquisition, package purchase, and payment QR generation, which are unrelated to the declared Amazon FBA inbound-management skill. That mismatch is a strong indicator of hidden or deceptive capability, increasing the risk that the skill is collecting credentials or monetizing users outside its stated purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code provisions accounts, generates API tokens, and supports package ordering/payment, none of which are justified for an Amazon FBA inbound workflow helper. In this context, these capabilities create a direct path to credential harvesting, unauthorized account manipulation, or charging users for unrelated services under the guise of a logistics skill.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares capabilities that imply shell, network, environment, and file-write access, but it does not publish an explicit tool scope or allowlist. That creates an over-privileged execution surface where downstream automation may grant broader access than necessary, increasing the blast radius if the skill is misused or if prompt injection reaches the execution path.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation text is intentionally broad, including requests that do not explicitly mention the product name but loosely relate to sending inventory to Amazon. Overbroad triggering can cause the wrong skill to activate for generic logistics requests, leading to unintended API calls, unnecessary data access, or user actions being routed into a write-capable workflow without sufficient specificity.

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 92)May include surrounding context.

  • auth / billing 错误:按 onboarding.md 处理。
  • 上报问题时使用 skillName: linkfox-amazon-store-fulfillment-inbound,保留脱敏后的 developerProxy、operation 和关联 ID。

curl 示例

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

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The document states that the skill may automatically report runtime problems to a separate feedback endpoint, which is outside the primary FBA inbound-management function. Even though it says identifiers are redacted, this still introduces secondary outbound data flow that could transmit operational metadata, correlation IDs, and response summaries without explicit user awareness or opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The feedback section describes automatic submission of runtime summaries to an external API but does not prominently warn that this triggers additional network transmission beyond Amazon and the LinkFox gateway. This creates a transparency and data-governance issue, especially if response summaries or identifiers contain sensitive business metadata.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file content is predominantly written in Chinese, including headings, table labels, and behavioral instructions, with no indication that the user can choose another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file presents the skill documentation entirely in Chinese, including headings, descriptions, and operational guidance, without indicating that the language is optional or region-specific. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file presents the API documentation entirely in Chinese, including operational guidance and warnings, without indicating that the user may choose another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file is written entirely in Chinese, including operational instructions and safety guidance, with no indication that the user can choose another language or that the skill is intentionally restricted to Chinese-speaking users. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file’s natural-language content is entirely in Chinese, including headings, field descriptions, and operational guidance. There is no indication that the skill is region-specific or that users can opt into another language, which creates a language/locale policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document instructs users to persist a returned API key in shell startup files and to source those files immediately, but it does not warn that this stores a long-lived credential in plaintext on disk. That increases the chance of accidental disclosure through backups, dotfile syncing, shared accounts, or later shell/environment leakage.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The entire workflow documentation is written in Chinese and provides no indication that users may choose another language or locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The natural-language instructions specify the script's default output policy entirely in Chinese and state fixed behavior such as '始终' for how results are emitted. This indicates a language/locale constraint without offering the user a choice or documenting an opt-in, which matches the policy-violation category for forced language behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module documentation explicitly promises writes only under the current working directory and forbids /tmp, but the implementation silently falls back to home-directory and temporary-directory storage. This mismatch can cause sensitive API responses to be written to less controlled locations than operators expect, increasing the risk of data leakage, accidental retention, or cross-process exposure on shared systems.

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_inbound_common.py (reported line 59)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,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code always serializes and saves full API responses to disk under a local session directory, including potentially sensitive seller, shipment, logistics, and document data. Persisting complete responses expands the exposure surface beyond the API call itself, especially on shared hosts or environments with weak filesystem isolation, and the manifest does not clearly justify this retention behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.