T09 · Insecure Skill Coding Practices
Error
- Location
- skills/_easybuy_browser_runtime.js:56
- Finding
- Weak Amazon Hostname Validation Permits Navigation to Attacker-Controlled Domains<![CDATA[ ## Vulnerability Details **File Location**: `skills/_easybuy_browser_runtime.js`, lines 56-80 **Vulnerability Type**: Improper hostname allowlist validation **Risk Level**: High ### Vulnerable Code ```javascript function amazonBase(origin) { if (!origin) return "https://www.amazon.com"; try { const u = new URL(String(origin)); if (["http:", "https:"].includes(u.protocol) && /amazon\./i.test(u.hostname)) { return `${u.protocol}//${u.host}`; } } catch { } return "https://www.amazon.com"; } function isTrustedAmazonUrl(raw) { try { const u = new URL(String(raw)); const hostOk = /(^|\.)amazon\./i.test(String(u.hostname || "")); return u.protocol === "https:" && hostOk; } catch { return false; } } function sanitizeAmazonUrl(raw, fieldName = "url") { const value = String(raw || "").trim(); if (!value) throw new Error(`${fieldName}_missing`); if (!isTrustedAmazonUrl(value)) throw new Error(`${fieldName}_not_allowed`); return new URL(value).toString(); } ``` ### Technical Analysis The runtime attempts to restrict browser navigation to Amazon by testing hostnames with regular expressions containing `amazon.`. These tests do not verify that the hostname is an Amazon-owned registrable domain. For example, all of the following attacker-controlled hostnames satisfy at least one of the checks: - `amazon.evil.example` - `x.amazon.evil.example` - `amazon.example.org` The `amazonBase` check is additionally weaker because it accepts any hostname containing `amazon.` and permits both HTTP and HTTPS. The affected value is used to construct order and product URLs. The public dispatcher forwards user-controlled JSON properties to the runtime without enforcing the generated input schemas. This is an allowlist bypass rather than a direct disclosure of Amazon cookies: browser cookie scoping normally prevents Amazon cookies from being sent to unrelated domains. Nevertheless, the bypass moves authenticated workflo ...[truncated 1823 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace substring regular expressions with an explicit domain allowlist. 2. Compare parsed, normalized hostnames rather than the complete URL string. 3. Permit only HTTPS, including in `amazonBase`. 4. Validate the final URL immediately before every navigation. 5. Verify the URL again after redirects and abort if the final origin is not approved. 6. Consider maintaining a deliberate marketplace allowlist rather than accepting every domain containing the Amazon brand. Example hardening: ```javascript const ALLOWED_AMAZON_HOSTS = new Set([ "www.amazon.com", "amazon.com" ]); function isAllowedAmazonHost(hostname) { const host = String(hostname || "").toLowerCase().replace(/\.$/, ""); return ALLOWED_AMAZON_HOSTS.has(host); } function sanitizeAmazonUrl(raw, fieldName = "url") { const value = String(raw || "").trim(); if (!value) throw new Error(`${fieldName}_missing`); const url = new URL(value); if (url.protocol !== "https:" || !isAllowedAmazonHost(url.hostname)) { throw new Error(`${fieldName}_not_allowed`); } return url.toString(); } ``` If marketplace subdomains are required, allow them only as suffixes of a specific registrable domain: ```javascript host === "amazon.com" || host.endsWith(".amazon.com") ``` Do not use checks such as `host.includes("amazon.")`. ]]>
