Fix SSRF (Server Side Request Forgery) in Fresh
SSRF (Server-Side Request Forgery) in Fresh/Deno environments occurs when an attacker manipulates the server into making unauthorized requests to internal or external resources. Because Fresh handles server-side logic in route handlers, an unvalidated fetch() call can be weaponized to scan internal networks, hit cloud metadata services (like 169.254.169.254), or bypass firewalls. If you are piping user-supplied URLs directly into fetch(), you are opening a hole into your infrastructure.
The Vulnerable Pattern
// routes/api/proxy.ts import { Handlers } from "$fresh/server.ts";export const handler: Handlers = { async GET(req) { const url = new URL(req.url); const target = url.searchParams.get(“url”);
// VULNERABLE: The server fetches any URL provided by the user. // Attacker can pass: ?url=http://169.254.169.254/latest/meta-data/ const resp = await fetch(target!); const data = await resp.text(); return new Response(data);
} };
The Secure Implementation
The fix implements a 'Deny-by-Default' strategy. First, it uses the native URL constructor to parse the input, preventing basic obfuscation bypasses. Second, it restricts the protocol to 'https:' to prevent access to local files (file://) or legacy protocols. Third, it implements a strict hostname allowlist. This prevents the attacker from targeting localhost, internal IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), or cloud provider metadata endpoints. For maximum security in Deno, use the --allow-net flag to restrict the runtime's network access at the OS level.
// routes/api/proxy.ts import { Handlers } from "$fresh/server.ts";const ALLOWED_HOSTS = [“api.trusted-partner.com”, “cdn.myapp.com”];
export const handler: Handlers = { async GET(req) { const url = new URL(req.url); const targetParam = url.searchParams.get(“url”);
if (!targetParam) return new Response("Missing URL", { status: 400 }); try { const targetUrl = new URL(targetParam); // 1. Enforce HTTPS only if (targetUrl.protocol !== "https:") { return new Response("Insecure protocol", { status: 403 }); } // 2. Strict Hostname Allowlisting if (!ALLOWED_HOSTS.includes(targetUrl.hostname)) { return new Response("Disallowed target", { status: 403 }); } const resp = await fetch(targetUrl.href); return new Response(resp.body, { headers: { "Content-Type": "application/json" } }); } catch (_) { return new Response("Invalid URL format", { status: 400 }); }
} };
Your Fresh API
might be exposed to SSRF (Server Side Request Forgery)
74% of Fresh 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.