jo3t / app /utils /url.ts
samifalouti1
Fresh start without binaries
55d48a7
/**
* 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;
}