T09 · Insecure Skill Coding Practices
- Location
scripts/_shop_product_common.py:15- Finding
Credential-Bearing Requests Can Be Redirected to an Untrusted or Plaintext Gateway
- Content
View full analysis
str: 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", "SESSION_ID": os.environ.get("SESSION_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), }, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) except HTTPError as e: body = e.read().decode("utf-8") if e.fp else "" return {"error": f"HTTP {e.code}: {e.reason}", "details": body} except URLError as e: return {"error": f"Connection failed: {e.reason}"} ``` ### Technical Analysis The Skill permits the developer-proxy destination to be replaced through either `LINKFOX_TOOL_GATEWAY` or `TIKTOK_SHOP_API_BASE_URL`. The selected URL is used without enforcing HTTPS, validating the hostname, or restricting the port and URL components. Every API request then transmits the following information to the selected destination: - The ...[truncated 2243 chars]- Remediation
View remediation
str: parsed = urlparse(value) if parsed.scheme != "https": raise ValueError("The LinkFox gateway must use HTTPS") if parsed.hostname not in ALLOWED_GATEWAY_HOSTS: raise ValueError("Untrusted LinkFox gateway host") if parsed.username or parsed.password or parsed.query or parsed.fragment: raise ValueError("Invalid gateway URL components") if parsed.port not in (None, 443): raise ValueError("Unexpected gateway port") return value.rstrip("/") ``` ]]>
