GuardAPI Logo
GuardAPI

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’ }); } });

System Alert • ID: 9979
Target: Nitro API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.