Back to skill

Security audit

亚马逊-店铺授权

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches Amazon store authorization, but it also handles login, billing/payment, feedback reporting, and sensitive local storage in ways users should review carefully.

Review before installing. Use this only with trusted LinkFox endpoints, avoid custom gateway environment overrides unless you control them, store API keys in a proper secret manager instead of shell startup files, avoid onboarding or payment flows unless you intended to use LinkFox account billing, and clear the local linkfox response files if they may contain store identifiers or authorization data.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/authorize_url.py:17
Finding

API Credentials Can Be Exfiltrated Through Unvalidated Gateway Overrides

Content
View full analysis
dict: api_key = get_api_key() data = json.dumps(params).encode("utf-8") req = Request( API_ENDPOINT, data=data, headers={ "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/1.0", }, method="POST", ) with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` ### Technical Analysis The clients accept an arbitrary gateway base URL from environment variables and subsequently transmit the LinkFox API key in the `Authorization` header. There is no validation of the URL scheme, hostname, port, embedded credentials, or destination. Although a configurable endpoint can be useful for development, sending a production credential to any environment-selected destination exceeds the minimum privilege necessary for normal Skill operation. In particular, the implementation does not require HTTPS and does not restrict credentials to the documented LinkFox gateway. The same unsafe endpoint-selection design is repeated across all store-management clients. The onboarding client also allows its login and user-service destinations to be overridden, including endpoints that receive ...[truncated 1392 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_token_status_output.py:22
Finding

Shallow Token Redaction Can Leak Legacy Amazon Credentials

Content
View full analysis
dict: out = dict(result) out.pop("accessToken", None) out.pop("refreshToken", None) return out ``` ```python result = call_api(params) result = strip_raw_tokens(result) emit_result(result, lf_inline_flag()) print_status_note(result) ``` ### Technical Analysis The redaction function only removes the exact keys `accessToken` and `refreshToken` from the top-level response object. It does not inspect nested dictionaries or lists and does not recognize alternative names such as: - `access_token` - `refresh_token` - `token` - `credentials` - Differently cased variants - Token fields nested under `data`, `result`, or list entries The Skill documentation explicitly acknowledges that legacy gateways may still return raw tokens. A response such as the following bypasses the current redaction: ```json { "data": { "accessToken": "Atza|sensitive-value", "refreshToken": "Atzr|sensitive-value" } } ``` After shallow redaction, both nested tokens remain. The complete result is then passed to `emit_result`, which writes it to disk and may print it to stdout. ### Attack Path 1. A legacy, compromised, or unexpectedly structured gateway response includes raw Amazon tokens inside a nested object or under an alternate key. 2. `strip_raw_tokens` copies the top-level dictionary and removes only two top-level fields. 3. Nested or alternately named token values remain in the response. 4. `emit_result` stores the remaining response in plaintext. 5. For responses at or below the output threshold, or when `--inline` is used, the raw token is also printed to stdout. 6. Terminal logs, Agent transcripts, CI logs, workspace readers, or local ...[truncated 577 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_lf_output.py:18
Finding

Complete API Responses Are Persisted in Plaintext and May Fall Back to Temporary Storage

Content
View full analysis
str: cached = _LF_SESSION_CACHE.get("_root") if cached: return cached candidates = [] acpx = (os.environ.get("ACPX_WORKSPACES") or "").strip() if acpx: acpx = acpx.split(os.pathsep)[0].strip() if acpx: candidates.append(os.path.join(acpx, "linkfox")) candidates.append(os.path.join(os.getcwd(), "linkfox")) candidates.append(os.path.join(os.path.expanduser("~"), "linkfox")) candidates.append(os.path.join(_lf_tempfile.gettempdir(), "linkfox")) for root in candidates: try: os.makedirs(root, exist_ok=True) probe = os.path.join(root, ".write_probe") with open(probe, "w", encoding="utf-8") as f: f.write("") os.remove(probe) except OSError: continue root = os.path.abspath(root) _LF_SESSION_CACHE["_root"] = root return root ``` ```python def emit_result(result, slug=SLUG, inline=False): serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join(data_dir, f"{slug}-{int(ts * 1_000_000)}.json") try: with open(out, "w", encoding="utf-8") as f: f.write(serialized) ``` ### Technical Analysis Every response is written in full using default filesystem permissions. The implementation does not: - R ...[truncated 1663 chars]
Remediation
View remediation

other

Warning
Location
SKILL.md:230
Finding

Automatic Feedback Reporting Can Disclose User Conversation Content Without Explicit Consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:454
Finding

Onboarding Prints Generated API Keys in Full and Recommends Long-Lived Plaintext Storage

Content
View full analysis
dict: hdr = _headers("agent-linkfox-web", "ai.linkfox.com", access_token=access_token, user_id=user_id, group_id=group_id) for path, source in (("/group/getApiToken", "existing"), ("/group/generateApiToken", "generated")): resp = _http_post(f"{_agent_user_base()}{path}", {"id": group_id}, hdr) if "_error" in resp: return {"error": f"{path.rsplit('/', 1)[-1]}: {resp.get('_body') or resp['_error']}"} tok = _extract_token(resp) if tok: return {"api_key": tok, "source": source} ``` ```python 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)) ``` The onboarding instructions recommend: ```bash echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc ``` ### Technical Analysis The onboarding command returns the complete generated API key in a JSON object and prints it to stdout. In Agent-driven environments, stdout commonly enters the conversation transcript, command logs, terminal scrollback, CI output, or execution telemetry. The documentation additionally recommends writing the key into shell startup files. These files are long-lived plaintext configuration files and can be exposed thr ...[truncated 1186 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
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 guidance instructs users to install `qrcode`, `pillow`, and `requests` without exact versions, hashes, a lockfile, an isolated environment, or an explicitly trusted package index. The package names are legitimate and there is no evidence that this project intentionally retrieves a malicious dependency. The risk arises from mutable dependency resolution and the user’s active pip configuration. A compromised mirror, unexpected index, or future incompatible release could supply unreviewed code. Python packages execute code during installation and import, so dependency installation represents a code-execution boundary. ### Attack Path 1. A required module is absent. 2. The script emits an instruction to run an unpinned `pip install` command. 3. The user executes the command in the current Python environment. 4. pip resolves the package from the configured index without hash verification. 5. A compromised index, substituted artifact, or malicious dependency release is installed. 6. Package installation or later import executes attacker-controlled code with the user’s privileges. ### Impact Assessment A malicious dependency would execute with the privileges of the user running pip or the Skill. It could access environment variables containing LinkFox API ke ...[truncated 304 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 (50)

Tainted flow: 'req' from os.environ.get (line 47, 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/authorize_url.py (reported line 59)May include surrounding context.

python
)

    try:
        with urlopen(req, timeout=150) as response:
            result = json.loads(response.read().decode("utf-8"))
            error_code = str(result.get("errcode", ""))
            if error_code.isdigit() and 1500 <= int(error_code) <= 1599:

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

Critical
Category
Data Flow
Confidence
92% confidence
Finding

The request destination is derived from environment-controlled base URL values, then used directly in urlopen together with the Authorization API key header. If an attacker can influence the environment, they can redirect the request to an attacker-controlled host and exfiltrate the API key or collect store metadata. In a credential-management skill, this is more dangerous because the script handles authorization state and potentially sensitive account linkage information.

Content

Scanner excerpt · scripts/authorized_stores.py (reported line 58)May include surrounding context.

python
)

    try:
        with urlopen(req, timeout=150) as response:
            result = json.loads(response.read().decode("utf-8"))
            error_code = str(result.get("errcode", ""))
            if error_code.isdigit() and 1500 <= int(error_code) <= 1599:

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

Critical
Category
Data Flow
Confidence
98% confidence
Finding

The request destination is indirectly controllable through environment variables such as LINKFOX_TOOL_GATEWAY, STORE_API_BASE_URL, and SPAPI_BASE_URL. Because the script also sends the Authorization API key and user-supplied seller data to that URL, an attacker who can influence the environment can redirect the request to an attacker-controlled endpoint and exfiltrate credentials and operational data.

Content

Scanner excerpt · scripts/cancel_authorization.py (reported line 133)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            body = response.read().decode("utf-8")
            result = _decode_gateway_response(body)
            return _attach_gateway_cost_headers(result, response.headers)

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The script builds request targets from environment-controlled base URLs and then sends sensitive authentication material to them via requests.post. Because the same flow carries SMS login data, access tokens, refresh tokens, or generated API keys, a tampered environment can redirect secrets to an attacker-controlled endpoint or internal service, making this a real SSRF/exfiltration risk.

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 URL is derived from environment variables and then used by urllib.request.urlopen together with the LinkFox API key in the Authorization header. An attacker who can influence the runtime environment can redirect these authenticated requests to a malicious host or internal network target, causing credential leakage and possible SSRF against internal services.

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

Tainted flow: 'req' from os.environ.get (line 48, 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/refresh_token.py (reported line 60)May include surrounding context.

python
)

    try:
        with urlopen(req, timeout=150) as response:
            result = json.loads(response.read().decode("utf-8"))
            error_code = str(result.get("errcode", ""))
            if error_code.isdigit() and 1500 <= int(error_code) <= 1599:

Tainted flow: 'req' from os.environ.get (line 48, 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/store_tokens.py (reported line 60)May include surrounding context.

python
)

    try:
        with urlopen(req, timeout=150) as response:
            result = json.loads(response.read().decode("utf-8"))
            error_code = str(result.get("errcode", ""))
            if error_code.isdigit() and 1500 <= int(error_code) <= 1599:

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to manage Amazon authorization, but its instructions also mandate generic response persistence, session data storage, and metadata/index maintenance. Hidden persistence behavior expands the data-handling surface beyond the stated purpose and can cause sensitive authorization metadata or API responses to be stored locally without clear expectation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims to manage Amazon authorization, but its instructions also mandate generic response persistence, session data storage, and metadata/index maintenance. Hidden persistence behavior expands the data-handling surface beyond the stated purpose and can cause sensitive authorization metadata or API responses to be stored locally without clear expectation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to manage Amazon authorization, but its instructions also mandate generic response persistence, session data storage, and metadata/index maintenance. Hidden persistence behavior expands the data-handling surface beyond the stated purpose and can cause sensitive authorization metadata or API responses to be stored locally without clear expectation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims to manage Amazon authorization, but its instructions also mandate generic response persistence, session data storage, and metadata/index maintenance. Hidden persistence behavior expands the data-handling surface beyond the stated purpose and can cause sensitive authorization metadata or API responses to be stored locally without clear expectation.

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 · SKILL.md (reported line 3)May include surrounding context.

md
---
name: linkfox-amazon-store-auth
description: 亚马逊卖家店铺授权与账号连接管理。用于生成授权链接、绑定店铺、查询已授权店铺、检查授权状态、刷新访问令牌和本地取消/解绑授权;生成授权链接时需要 sellerName 区分店铺。用户提到亚马逊店铺授权、绑定或连接 Amazon Seller 账号、查看已授权店铺、授权失效、刷新令牌、token 状态、取消授权、解绑店铺、停用授权、Amazon seller authorization、bind seller account、refresh access token、disconnect seller account 时触发。即使未明确说“授权”,只要其他亚马逊店铺操作因未绑定店铺、凭证过期或需要选择授权账号而无法继续,也应触发此技能。
---

# Amazon 店铺授权与管理

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 · scripts/refresh_token.py (reported line 4)May include surrounding context.

python
---
name: linkfox-amazon-store-auth
description: 亚马逊卖家店铺授权与账号连接管理。用于生成授权链接、绑定店铺、查询已授权店铺、检查授权状态、刷新访问令牌和本地取消/解绑授权;生成授权链接时需要 sellerName 区分店铺。用户提到亚马逊店铺授权、绑定或连接 Amazon Seller 账号、查看已授权店铺、授权失效、刷新令牌、token 状态、取消授权、解绑店铺、停用授权、Amazon seller authorization、bind seller account、refresh access token、disconnect seller account 时触发。即使未明确说“授权”,只要其他亚马逊店铺操作因未绑定店铺、凭证过期或需要选择授权账号而无法继续,也应触发此技能。
---

# Amazon 店铺授权与管理

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

md
- 每家店铺的令牌与权限彼此独立
- 必须使用与店铺匹配的 `sellerId`+`region`,跳过「选店」会导致歧义和错误

## Display Rules

1. **先有店铺名再生成授权链接**:若用户未提供 `sellerName`,**必须先问**,不允许带空值调用 `/spApi/authorizeUrl`。
2. **只呈现数据**:展示授权结果、店铺列表、令牌信息即可,不做业务建议。

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file contains broad Linkfox account onboarding, SMS login, and billing recovery procedures that are unrelated to the declared Amazon seller authorization purpose of the skill. This scope expansion can cause the agent to collect credentials and personal data, steer users into unrelated platform registration/payment flows, and perform actions outside the user's expected consent boundary.

Content

No source excerpt is available for this finding.

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

md
示 JSON 里的 phone/agreements
   - 收到验证码后:`python scripts/onboarding.py login <phone> <code>`
   - 拿到 `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_AGENT_API_KEY`(主推)或 `LINKFOXAGENT_API_KEY`(老规范)任一即可

**billing 场景**:`errcode=402` 或消息含 `算力/余额/quota/insufficient/充值/套餐到期`。
- `python scripts/onboarding.py list-plans` → 有 AskUserQuestion 就弹菜单,否则输出编号清单让用户选
- 校验 `plan_id` ∈ 清单、支付方式 ∈ 该套餐 `available_methods`(通常 `wechat/alipay`)
- `python scripts/onboarding.py order <plan_id> <method>` → 展示优先级 PNG

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The billing section instructs the agent to list plans, create orders, and guide payment for Linkfox platform services, which is unrelated to Amazon seller store authorization. Embedding payment handling in this skill increases the risk of unauthorized commercial redirection, user confusion, and misuse of the agent to facilitate purchases the user did not intend through this workflow.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file advertises a cancelAuthorization operation, but the final success message tells the user that Amazon authorization was not revoked and only a local connection was removed. This mismatch can mislead operators into believing third-party marketplace access has been fully revoked when valid Amazon-side authorization or tokens may still remain active, creating a dangerous false sense of deauthorization.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements LinkFox account onboarding, login, API key issuance, package purchase, and payment flows, which are materially unrelated to the declared Amazon seller store authorization purpose. In a skill ecosystem, such scope divergence is dangerous because it can trick users into disclosing phone numbers, SMS codes, tokens, or making purchases under the guise of an Amazon authorization workflow.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Adding plan listing, order creation, payment URL/QR generation, and order-status checks is unjustified for an Amazon seller authorization skill and creates an unexpected monetization path. This mismatch increases the likelihood of deceptive behavior, unauthorized charges, or social engineering by presenting payment actions as necessary prerequisites for store authorization.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The primary skill description is written in Chinese and does not indicate that users may interact in other languages or choose a preferred locale. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation unless the constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill describes capabilities that access environment variables, write files, and make network requests, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates an unnecessary trust gap: operators and users cannot easily tell what execution surface the skill requires, and a broad runtime may permit unintended data access or persistence.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill content and prescribed user interaction are written entirely in Chinese, and the description does not indicate that the agent should adapt to the user's preferred language. That can amount to a locale/language policy issue if users are not given an opt-in or alternative language path.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger description is intentionally broad, including cases where any Amazon store task cannot continue because authorization might be needed. Over-broad activation can cause the skill to run in unrelated workflows, increasing chances of unnecessary account enumeration, token-status checks, or persistence of store/account metadata.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs scripts to always write full API responses to local disk under a session-based directory, and to print full JSON to stdout for smaller responses. Authorization and store-management responses may contain seller identifiers, token metadata, error details, or even legacy token fields, so unconditional persistence materially increases exposure through local files, logs, backups, and shared workspaces.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.