Back to skill

Security audit

Linkfox 亚马逊店铺运营

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real Amazon seller operations toolkit, but it handles powerful seller credentials and data with several unsafe, under-scoped behaviors that could expose tokens, reports, or local files if misconfigured or misused.

Install only if you trust LinkFox with Amazon seller operations. Use a dedicated workspace, do not set LINKFOX_TOOL_GATEWAY/STORE_API_BASE_URL/SPAPI_BASE_URL unless it is an official trusted HTTPS LinkFox endpoint, avoid --inline for sensitive results, disable or keep report HTTP serving on 127.0.0.1, and confirm every write/delete/upload operation and source file path before running it.

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/_spapi_orders_common.py:18
Finding

Configurable Gateway Can Redirect API Keys and Amazon Access Tokens to an Untrusted Host

Content
View full analysis
str: """ 获取配置在环境变量的API Key。 如果获取不到,按 SKILL.md 的 **## 解决认证和积分问题** 处理。 """ key = os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get("LINKFOXAGENT_API_KEY") if not key: print( "API Key 未配置", file=sys.stderr, ) sys.exit(1) return key def call_api(endpoint: str, params: dict) -> dict: api_key = get_api_key() data = json.dumps(params).encode("utf-8") req = Request( endpoint, data=data, headers={ "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/1.0", }, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` The same endpoint-selection and request pattern is replicated across other `_spapi_*_common.py` modules and several standalone API scripts. ### Technical Analysis The gateway base URL is accepted directly from environment variables without validating: - The URL scheme. - The destination hostname. - The destination port. - Embedded URL credentials. - Redirect behavior. - Whether the destination is an approved LinkFox service. Every request adds the LinkFox API key to the `Authorization` header. Developer-proxy requests also include the Amazon access token in the JSON request body u ...[truncated 1552 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/upload_to_destination.py:30
Finding

Arbitrary Upload URL and Local File Path Enable Data Exfiltration

Content
View full analysis
tuple[str, dict]: dest = params.get("uploadDestination") if isinstance(dest, dict): url = dest.get("url") or params.get("uploadUrl") headers = dest.get("headers") or params.get("headers") or {} else: url = params.get("uploadUrl") headers = params.get("headers") or {} if not url: print("Missing uploadUrl or uploadDestination.url", file=sys.stderr) sys.exit(1) if not isinstance(headers, dict): print("headers must be a JSON object", file=sys.stderr) sys.exit(1) return str(url).strip(), {str(k): str(v) for k, v in headers.items()} def main() -> None: params = load_cli_params() if not params: print( "Usage: upload_to_destination.py ''\n" "Required: uploadUrl (or uploadDestination), headers, " "and filePath | content | contentBase64", file=sys.stderr, ) sys.exit(1) upload_url, hdrs = _resolve_upload_target(params) payload = load_file_bytes(params) if not payload: print("Provide filePath, content, or contentBase64", file=sys.stderr) sys.exit(1) req = Request(upload_url, data=payload, headers=hdrs, method="PUT") out: dict = { "uploadUrl": upload_url, "bytesUploaded": len(payload), "requestHeaders": hdrs, } try: with urlopen(req, timeout=300) as resp: out["httpStatus"] = resp.status out["success"] = 200 <= resp.status < 300 ``` ### Technical Analysis The script allows the caller to independently control: - The complete upload destination URL. - Arbitrary HTTP request headers. - A local file path loaded by `load_file_bytes`. - Alternat ...[truncated 1578 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/get_report.py:282
Finding

Sensitive Amazon Reports Can Be Served on an Unauthenticated External Interface

Content
View full analysis
tuple[ThreadingHTTPServer, threading.Thread, str]: """ Serve the extracted report file over HTTP on localhost so the user can download the **already decompressed** file via a browser or curl. Only paths '/' and '/download' are served. Bind defaults to 127.0.0.1. """ file_abs = file_abs.resolve() if not file_abs.is_file(): raise FileNotFoundError(str(file_abs)) safe_name = file_abs.name.replace('"', "").replace("\\", "") or "report.txt" holder: dict[str, Path] = {"p": file_abs} class OneFileHandler(BaseHTTPRequestHandler): def log_message(self, fmt, *args) -> None: return def do_GET(self) -> None: # noqa: N802 path = self.path.split("?")[0] if path not in ("/", "/download"): self.send_error(404) return p = holder["p"] if not p.is_file(): self.send_error(410, "Report file no longer available") return try: self.send_response(200) self.send_header("Content-Type", "application/octet-stream") self.send_header( "Content-Disposition", f'attachment; filename="{safe_name}"', ) self.send_header("Content-Length", str(p.stat().st_size)) self.end_headers() with p.open("rb") as fp: shutil.copyfileobj(fp, self.wfile) except BrokenPipeError: return except Exception: if not self.wfile.closed: try: ...[truncated 2664 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:487
Finding

Onboarding Prints the Complete Generated API Key to Standard Output

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} 成功获取 API key(来源: {r['source']})", file=sys.stderr) return 0 return 1 ``` ### Technical Analysis `login_and_get_key` returns the full API key in a dictionary. `_cmd_login` then serializes the complete dictionary to standard output without masking or using a protected secret channel. In an Agent environment, stdout may be captured in: - Conversation transcripts. - Tool-call history. - Process logs. - Debugging or observability systems. - Terminal scrollback. - Automation output artifacts. The key is therefore exposed beyond the minimum component that needs it. A success message could be printed without disclosing the secret itself. ### Attack Path 1. A user completes SMS-based onboarding. 2. The script retrieves or generates the LinkFox API key. 3. `_cmd_login` passes the result to `_emit`. 4. `_emit` prints the complete key as JSON. 5. A party with access to the transcript, logs, terminal history, or captured process output obtains the key. 6. The party uses the key against LinkFox gateway services until it is revoked or expires. ### Impact Assessment The exposed key may authorize gateway calls, consume the victim's paid balance, and provide access to capabilities assoc ...[truncated 263 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
references/linkfox-amazon-store-auth.md:164
Finding

Onboarding Recovery Instructions Install an Unpinned Remote Archive Without Integrity Verification

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (307)

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request target is derived from environment variables that can override the default gateway, and the same request carries the API key in the Authorization header plus user-supplied seller data. If an attacker can influence the runtime environment, they can redirect this POST to an arbitrary host and exfiltrate credentials and seller information; this is especially relevant in agent/plugin execution environments where env injection is plausible.

Content

Scanner excerpt · scripts/authorize_url.py (reported line 59)May include surrounding context.

python
)

    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 46, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request target is derived from environment variables that can override the default gateway URL, and that tainted value is used directly in a network call. In an agent or multi-tenant execution environment, a malicious party who can influence environment variables could redirect the request to an attacker-controlled endpoint and cause the Authorization API key to be exfiltrated in the request headers.

Content

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

python
)

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

The code constructs request destinations from environment-controlled base URLs and then sends sensitive authentication material to those endpoints, including access tokens, API keys, phone numbers, and SMS codes. If an attacker can influence environment variables in the skill runtime, they can redirect traffic to an attacker-controlled host and exfiltrate credentials or order/payment data.

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

The gateway request uses a URL derived from environment variables and attaches the LinkFox API key in the Authorization header before calling urlopen. In a hostile or misconfigured agent environment, this enables SSRF-style redirection of authenticated requests and direct credential leakage to untrusted infrastructure.

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

python
)

    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 47, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request destination is derived from environment variables (LINKFOX_TOOL_GATEWAY / STORE_API_BASE_URL / SPAPI_BASE_URL) and then used directly for an authenticated outbound POST carrying the API key in the Authorization header. In an agent or untrusted runtime, environment variables can be attacker-controlled, which can redirect the request to an arbitrary host and exfiltrate the credential and seller-related request data.

Content

Scanner excerpt · scripts/store_tokens.py (reported line 59)May include surrounding context.

python
)

    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 ""

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| linkfox-amazon-store-fba | references/linkfox-amazon-store-fba.md | POST /spApi/developerProxy(fba/inbound/v1/*、fba/inventory/v1/*、fba/inbound/v0/*、inbound/fb

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The callback example places access_token and refresh_token in a URL query string. Query strings are commonly logged by reverse proxies, application servers, browser history, analytics tools, and referrer headers, so this pattern can leak credentials broadly and silently, especially for a refresh token that grants durable re-access.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The document states that tokens are 'not exposed to the frontend,' yet earlier API definitions for /spApi/refreshToken and /spApi/storeTokens explicitly return accessToken and refreshToken to the caller. This contradiction is dangerous because it normalizes sending long-lived credentials to client-facing consumers, increasing risk of theft via logs, browser storage, agent transcripts, or downstream integrations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly states that complete API responses are always written to disk and may be fully printed to stdout, while the same document defines token-bearing responses for /spApi/storeTokens and /spApi/refreshToken. This creates a clear secret exposure path: accessToken and refreshToken can be persisted in plaintext, captured in logs, terminal history, transcripts, or agent context despite later guidance saying tokens should not be shown in full.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

These instructions normalize full-response logging and optional full stdout emission for responses that can contain OAuth credentials. In an agent setting, stdout and saved JSON are often ingested into chat context, observability systems, and shared workspaces, so this is a practical data leakage channel rather than a purely theoretical one.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The examples and described outputs for refresh and token retrieval return complete token material, which encourages both the agent and operators to treat secrets as ordinary output. In a skill whose purpose is authentication and token brokerage, this context makes exposure especially dangerous because the returned tokens can directly authorize downstream Amazon SP-API access.

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/linkfox-amazon-store-auth.md (reported line 153)May include surrounding context.

md
| "授权我的亚马逊店铺" / "Authorize my Amazon store" | 新店铺授权 |
| "看看已授权的亚马逊店铺" / "Show my authorized stores" | 列出已授权店铺 |
| "令牌过期了" / "My token expired" | 刷新令牌 |
| "获取 XXX 店铺的访问令牌" / "Get access token for store" | 查询店铺令牌 |
| "绑定我的亚马逊账号" / "Connect my Amazon seller account" | 新店铺授权 |

不适用场景见上方【能力边界】。

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/linkfox-amazon-store-orders.md (reported line 156)May include surrounding context.

md
| "授权我的亚马逊店铺" / "Authorize my Amazon store" | 新店铺授权 |
| "看看已授权的亚马逊店铺" / "Show my authorized stores" | 列出已授权店铺 |
| "令牌过期了" / "My token expired" | 刷新令牌 |
| "获取 XXX 店铺的访问令牌" / "Get access token for store" | 查询店铺令牌 |
| "绑定我的亚马逊账号" / "Connect my Amazon seller account" | 新店铺授权 |

不适用场景见上方【能力边界】。

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/linkfox-amazon-store-external-fulfillment.md (reported line 1)May include surrounding context.

md
---
name: linkfox-amazon-store-fba
description: 亚马逊店铺 Fulfillment by Amazon(FBA)系列(与 linkfox-amazon-store-auth 同系列),经 /spApi/developerProxy 调用 SP-API:FBA Inbound Eligibility(getItemEligibilityPreview)、FBA Inventory(getInventorySummaries/createInventoryItem/deleteInventoryItem/addInventory)、Fulfillment Inbound v2024-03-20(InboundPlan/装箱/放置/运输/货件等)与 v0(prepInstructions/labels/BOL/shipments)、Fulfillment Outbound 2020-07-01(MCF 履约单/预览/退货/tracking/features)。当用户提到 FBA、入仓资格、Inbound Eligibility、FBA 库存摘要、Send to Amazon、Inbound Plan、FBA 货件、MCF、多渠道履约、getItemEligibilityPreview、getInventorySummaries、createInboundPlan、createFulfillmentOrder 时触发。与 External Fulfillment / 普通 Orders 不同。
---

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/linkfox-amazon-store-fba.md (reported line 1)May include surrounding context.

md
---
name: linkfox-amazon-store-fba
description: 亚马逊店铺 Fulfillment by Amazon(FBA)系列(与 linkfox-amazon-store-auth 同系列),经 /spApi/developerProxy 调用 SP-API:FBA Inbound Eligibility(getItemEligibilityPreview)、FBA Inventory(getInventorySummaries/createInventoryItem/deleteInventoryItem/addInventory)、Fulfillment Inbound v2024-03-20(InboundPlan/装箱/放置/运输/货件等)与 v0(prepInstructions/labels/BOL/shipments)、Fulfillment Outbound 2020-07-01(MCF 履约单/预览/退货/tracking/features)。当用户提到 FBA、入仓资格、Inbound Eligibility、FBA 库存摘要、Send to Amazon、Inbound Plan、FBA 货件、MCF、多渠道履约、getItemEligibilityPreview、getInventorySummaries、createInboundPlan、createFulfillmentOrder 时触发。与 External Fulfillment / 普通 Orders 不同。
---

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 · references/linkfox-amazon-store-external-fulfillment.md (reported line 114)May include surrounding context.

md
共享模块:`_spapi_fba_common.py`、`_fba_endpoints.py`、`_fba_runner.py`(非独立 CLI)。

## Display Rules

1. 先看 `developerProxy.errcode` / `httpStatus`,再看解析字段 **`payload`**
2. 202/204 可能无 body;以状态码判断成功

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 · references/linkfox-amazon-store-fba.md (reported line 91)May include surrounding context.

md
共享模块:`_spapi_fba_common.py`、`_fba_endpoints.py`、`_fba_runner.py`(非独立 CLI)。

## Display Rules

1. 先看 `developerProxy.errcode` / `httpStatus`,再看解析字段 **`payload`**
2. 202/204 可能无 body;以状态码判断成功

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs that complete order API responses are always written to disk, while the documented endpoints can include buyer information, shipping addresses, and other restricted order data. Persisting full responses by default without explicit minimization, masking, retention, or access-control guidance creates a meaningful risk of local PII exposure and accidental data retention beyond operational need.

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
��后:`python scripts/onboarding.py login <phone> <code>`(workbuddy 宿主加 `--channel workbuddy`)
   - 拿到 `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>` → 展示优先�

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/get_report.py (reported line 160)May include surrounding context.

python
def get_store_tokens(seller_id: str, region: str) -> dict:
    """Get access tokens for the specified store."""
    print(f"🔑 Fetching access token for seller {seller_id} in region {region}...", file=sys.stderr)
    return call_api(STORE_TOKENS_ENDPOINT, {"sellerId": seller_id, "region": region})

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/get_report.py (reported line 377)May include surrounding context.

python
def get_store_tokens(seller_id: str, region: str) -> dict:
    """Get access tokens for the specified store."""
    print(f"🔑 Fetching access token for seller {seller_id} in region {region}...", file=sys.stderr)
    return call_api(STORE_TOKENS_ENDPOINT, {"sellerId": seller_id, "region": region})

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/get_report.py (reported line 384)May include surrounding context.

python
sys.exit(1)

    access_token = tokens_result["accessToken"]
    print("✓ Access token retrieved", file=sys.stderr)

    # Step 2: Create report request
    create_result = create_report(

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

md
#!/usr/bin/env python3
"""
Amazon Store Token Refresh - LinkFox Skill
Calls the /spApi/refreshToken endpoint to refresh access token

Usage:
  python refresh_token.py '{"sellerId": "A1234567890", "region": "NA"}'

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/get_report.py (reported line 161)May include surrounding context.

python
#!/usr/bin/env python3
"""
Amazon Store Token Refresh - LinkFox Skill
Calls the /spApi/refreshToken endpoint to refresh access token

Usage:
  python refresh_token.py '{"sellerId": "A1234567890", "region": "NA"}'

Static analysis

No suspicious patterns detected.