Why SSRF matters in a React world
Server-Side Request Forgery (SSRF) happens when your server makes HTTP requests to attacker-controlled URLs. While React runs in the browser, many React apps use Next.js server functions, API routes, proxies, or backend helpers—and that’s where SSRF creeps in.
Read more security posts on the Pentest Testing Corp's Blog.
Where it appears
-
Next.js
app/api/*
orpages/api/*
routes that “fetch a URL for me.” -
getServerSideProps
/ Server Actions fetching data using user input. - Dev/production proxies (Vite/CRA/Nginx) that forward to arbitrary targets.
Vulnerable example (Next.js API route)
// pages/api/proxy.ts
export default async function handler(req, res) {
const { url } = req.query; // ❌ untrusted input
const r = await fetch(url); // ❌ open fetch: SSRF risk
const body = await r.text();
res.status(200).send(body);
}
Attackers can hit metadata services (e.g., http://169.254.169.254
) or internal hosts.
Screenshot: Our free Website Vulnerability Scanner homepage
Screenshot of the free tools webpage where you can access security assessment tools.
Safer pattern: strict allowlist + protocol guard
// lib/ssrf.ts
const ALLOW = new Set(["api.example.com", "cdn.example.com"]);
export function isAllowed(urlStr: string) {
const u = new URL(urlStr);
if (!["http:", "https:"].includes(u.protocol)) return false; // block file:, gopher:
return ALLOW.has(u.hostname);
}
// pages/api/proxy.ts (fixed)
import { isAllowed } from "@/lib/ssrf";
export default async function handler(req, res) {
const url = String(req.query.url || "");
if (!isAllowed(url)) return res.status(400).json({ error: "Blocked" });
const r = await fetch(url, {
method: "GET",
redirect: "error",
signal: AbortSignal.timeout(3000), // short timeout
headers: { "User-Agent": "SafeProxy/1.0" }
});
const text = await r.text();
return res.status(200).send(text);
}
Tip: Keep the allowlist small; prefer IDs (e.g., resourceId
) over raw URLs.
Sample assessment report by our tool to check Website Vulnerability
Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.
Extra hardening (Express/Node proxy)
// middleware/deny-ssrf.js
import { isAllowed } from "./ssrf.js";
export function denySSRF(req, res, next) {
const target = req.query.url;
if (!target || !isAllowed(target)) return res.status(400).end("Blocked");
next();
}
Attach the middleware before any proxy handler.
Frontend usage (React)
// components/PreviewForm.tsx
const [url, setUrl] = useState("");
async function preview() {
const r = await fetch(`/api/proxy?url=${encodeURIComponent(url)}`);
const html = await r.text();
// render or sanitize appropriately
}
Key point: the UI never talks to arbitrary URLs directly; it calls the safe server route.
Quick SSRF checklist
- ✅ Accept IDs, resolve to known hosts on the server.
- ✅ Allowlist domains; block non-HTTP(S) schemes.
- ✅ Short timeouts, no redirects, minimal methods (GET/HEAD).
- ✅ Log and alert on blocked attempts.
- ✅ Test with a scanner for a Website Security check.
Services & resources
Managed IT Services
Harden endpoints, patching, monitoring, and incident response.
👉 Explore Managed IT Services
AI Application Cybersecurity
Threat modeling and testing for LLM/AI features (prompt injection, data exfiltration).
👉 AI Application Security
Partner Program
Offer security services to your clients with white-label delivery.
👉 Offer Cybersecurity to Your Client
Subscribe on LinkedIn: https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7327563980778995713
Try it now: Scan your site with our free Website Security Scanner → https://free.pentesttesting.com/
Top comments (0)