SSRF turns your backend into the attacker's proxy. If a feature accepts a URL and your server fetches it without restrictions, the attacker can often reach systems their browser never could: metadata endpoints, internal APIs, loopback services, private dashboards, and sensitive integration surfaces.
Modern startup products are full of URL-powered features: OG previews, PDF imports, webhook callbacks, crawl jobs, feed ingestion, image fetchers, file scanners, and AI tools that summarize remote pages. Each one looks like a harmless convenience until someone realizes the server will fetch almost anything it is asked to fetch.
That is why SSRF keeps appearing in cloud incidents. The browser can only see the public internet. Your server can usually see much more. If you do not force an allowlist and network boundaries, you are effectively handing attackers a backend network pivot built into your product.
Why SSRF Still Works in Cloud Apps
SSRF works because the trust model is backwards. A feature says “let the server fetch this URL for the user,” but the server has access the user does not. In a cloud environment that often includes metadata endpoints, internal dashboards, private service-to-service APIs, and anything bound to loopback or RFC1918 addresses.
The startup-specific risk is that SSRF almost always hides inside a perfectly legitimate product feature. Nobody creates an “SSRF endpoint.” They create a website preview, an import-from-URL tool, a Slack unfurl, or a crawler for lead enrichment. The vulnerability is in the lack of network policy around that feature.
Redirects make it worse. Even if the initial hostname looks safe, a redirect can bounce the request somewhere private unless you explicitly block it.
Common SSRF Entry Points in Startup Products
Link preview or OG image fetchers
A user pastes a URL and the backend retrieves remote HTML or metadata. Without an allowlist, that path can hit internal services.
Import-from-URL flows
CSV, PDF, or image imports often trust a user-supplied URL and fetch directly from the server for convenience.
Webhook validation or retry logic
Some systems fetch callback URLs or follow redirects while attempting delivery, which can create an unexpected SSRF surface.
AI tools that summarize a URL
AI features frequently accept a webpage URL, fetch the content server-side, and pass it into an LLM. That is still network access and needs hard limits.
Internal support utilities
Ops or support pages often have “fetch this URL” helpers for debugging integrations, then accidentally stay reachable in production.
Never Fetch a Raw User URL From the Server
If the server is going to make outbound requests, it needs a network policy just as much as your inbound API does.
export async function POST(req: Request) {
const { url } = await req.json();
const response = await fetch(url);
const html = await response.text();
return Response.json({ html });
}const ALLOWED_HOSTS = ['docs.stripe.com', 'developer.mozilla.org'];
export async function POST(req: Request) {
const { url } = await req.json();
const parsed = new URL(url);
if (parsed.protocol !== 'https:') {
return Response.json({ error: 'Only https URLs allowed' }, { status: 400 });
}
if (!ALLOWED_HOSTS.includes(parsed.hostname)) {
return Response.json({ error: 'Host not allowed' }, { status: 403 });
}
const response = await fetch(parsed.toString(), { redirect: 'error' });
return Response.json({ html: await response.text() });
}For broader products, use a resolver that blocks private IP ranges, loopback, metadata addresses, and unexpected redirects before the request leaves the server.
If a feature does not truly need arbitrary URL fetching, do not support it. Narrow the feature instead of widening the attack surface.
SSRF Defense Checklist for Startups
Allowlist domains when business logic permits it
AllowlistThe safest URL fetch feature is one that only talks to approved providers or customer-owned domains you explicitly expect.
Reject private, loopback, and metadata ranges
NetworkDo not let outbound requests reach 127.0.0.1, localhost, RFC1918 ranges, or 169.254.169.254.
Block unexpected redirects
RedirectsAn apparently safe public host can redirect to a private target unless the fetch layer stops it.
Time-box and size-box responses
LimitsEven benign external fetches should have strict timeouts and body-size limits so SSRF does not become a resource-drain attack.
Scan every fetch path in the repo
AutomationSearch for fetch(), axios, request, and SDK helpers that can receive user-controlled URLs through params, body fields, or database values.