UNPKG

@revenuecat/purchases-ui-js

Version:

Web components for Paywalls. Powered by RevenueCat

53 lines (52 loc) 1.99 kB
const SAFE_WEB_VIEW_PROTOCOL = "https:"; /** * Returns a sanitized URL if it is a well-formed absolute `https:` URL, * otherwise `null`. * * The web view embeds remote, third-party bundles, so only `https` is allowed: * `http`, `data:`, `blob:`, `javascript:`, protocol-relative (`//host`) and * relative URLs are all rejected, as are URLs carrying embedded credentials * (`https://user:pass@host`). Whitespace and control characters (code points * <= 0x20) are stripped before validation so obfuscated payloads such as * "https\t://" or "jAvAsCrIpT:" cannot slip through. The normalized, parsed * `href` is returned (not the raw input) so no control characters reach the * iframe `src`. */ export function sanitizeWebViewUrl(url) { const normalized = Array.from(url) .filter((character) => character.charCodeAt(0) > 0x20) .join(""); let parsed; try { parsed = new URL(normalized); } catch { return null; } if (parsed.protocol.toLowerCase() !== SAFE_WEB_VIEW_PROTOCOL) { return null; } // Reject embedded credentials: they have no place in an asset URL and can be // used to obscure the real host (e.g. `https://trusted.com@evil.com`). if (parsed.username !== "" || parsed.password !== "") { return null; } return parsed.href; } /** * Returns whether `url` resolves to the same origin as `hostOrigin` (typically * `window.location.origin`). Used as a guard before applying the * `allow-scripts allow-same-origin` sandbox: that combination is only safe when * the framed bundle is on a different origin than the host page, otherwise it * could script and un-sandbox the host. Callers should pass an already * sanitized URL; an unparseable URL conservatively reports `true` (treat as * same-origin -> block). */ export function isSameOriginAsHost(url, hostOrigin) { try { return new URL(url).origin === hostOrigin; } catch { return true; } }