Spaces:
Build error
Build error
| /** | |
| * URL validation utilities with SSRF protection. | |
| */ | |
| const PRIVATE_IP_PATTERNS = [ | |
| /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, // Loopback | |
| /^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, // Class A private | |
| /^172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}$/, // Class B private | |
| /^192\.168\.\d{1,3}\.\d{1,3}$/, // Class C private | |
| /^169\.254\.\d{1,3}\.\d{1,3}$/, // Link-local | |
| /^0\.0\.0\.0$/, // Unspecified | |
| ]; | |
| const BLOCKED_HOSTNAMES = new Set(['localhost', '[::1]', '0.0.0.0']); | |
| export function isValidUrl(input: string): boolean { | |
| try { | |
| const url = new URL(input); | |
| return url.protocol === 'http:' || url.protocol === 'https:'; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| export function isAllowedUrl(input: string): boolean { | |
| if (!isValidUrl(input)) { | |
| return false; | |
| } | |
| const url = new URL(input); | |
| const hostname = url.hostname.toLowerCase(); | |
| if (BLOCKED_HOSTNAMES.has(hostname)) { | |
| return false; | |
| } | |
| if (PRIVATE_IP_PATTERNS.some((pattern) => pattern.test(hostname))) { | |
| return false; | |
| } | |
| return true; | |
| } | |