Fix SSRF (Server Side Request Forgery) in Nitro
Nitro's event handlers and built-in $fetch make it trivial to proxy requests, but blind trust in user-supplied URLs is a one-way ticket to internal network exposure. SSRF in Nitro environments typically occurs when an attacker can control the destination of a server-side request, allowing them to probe internal metadata services (like 169.254.169.254), internal APIs, or databases that are not publicly accessible.
The Vulnerable Pattern
export default defineEventHandler(async (event) => {
const { url } = getQuery(event);
// VULNERABLE: Direct injection of user-controlled string into $fetch
const data = await $fetch(url);
return data;
});
The Secure Implementation
To kill SSRF in Nitro, you must implement a multi-layered defense. First, parse the input using the URL constructor to prevent obfuscation attacks. Second, enforce an allowlist of trusted hostnames; never allow arbitrary external requests if you can avoid it. Third, explicitly restrict the protocol to HTTPS to prevent usage of file://, gopher://, or dict:// schemes. For high-security environments, use a custom fetch agent to resolve the hostname and verify that the resulting IP address does not fall within private ranges (RFC 1918), preventing attackers from hitting the local network even if they bypass hostname checks via DNS rebinding.
import { createError } from 'h3';const ALLOWED_HOSTS = [‘api.trusted-partner.com’, ‘cdn.myapp.com’];
export default defineEventHandler(async (event) => { const { url: targetUrl } = getQuery(event);
try { const parsedUrl = new URL(targetUrl);
// 1. Enforce HTTPS only if (parsedUrl.protocol !== 'https:') { throw createError({ statusCode: 400, message: 'Invalid protocol' }); } // 2. Strict Hostname Allowlisting if (!ALLOWED_HOSTS.includes(parsedUrl.hostname)) { throw createError({ statusCode: 403, message: 'Forbidden destination' }); } // 3. Prevent DNS Rebinding / Private IP access (Advanced) // In production, use a custom fetch agent that validates resolved IPs return await $fetch(parsedUrl.href, { retry: 0, timeout: 5000 });
} catch (e) { throw createError({ statusCode: 400, message: ‘Invalid URL or target’ }); } });
Your Nitro API
might be exposed to SSRF (Server Side Request Forgery)
74% of Nitro apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.