Server fetches a URL the caller controls
An outbound HTTP request is made to a URL that came from the caller. The server can reach hosts the caller cannot - cloud metadata endpoints, internal admin services, databases bound to localhost - so this turns the server into a proxy into its own network. Validate the destination against an allowlist before fetching it.
high likely application source OWASP A10:2021 / CWE-918
What it looks like
From app/api/proxy/route.ts in the fixture suite.
The fixture test asserts this finding.
How to fix it
Check the destination against an allowlist of hosts before fetching it. Blocklists do not work here: DNS rebinding, redirects, and IPv6-mapped addresses all defeat them.
// lib/safe-fetch.ts
const ALLOWED_HOSTS = new Set(['api.partner.com', 'cdn.example.com'])
export function assertAllowedUrl(raw: string): URL {
const url = new URL(raw)
if (url.protocol !== 'https:') throw new Error('only https is allowed')
if (!ALLOWED_HOSTS.has(url.hostname)) throw new Error('host not allowed')
return url
}
The fix for your framework
Choose the API used by your project.
- Next.js
- Nuxt
- NestJS
- Express
- Fastify
- Hono
- Koa
- Hapi
- Sails.js
- Astro
- Remix
- Gatsby
- SvelteKit
- TanStack Start
- SolidStart
- Elysia
Check your own repository
npx owlwarden scan --preset deep
npx owlwarden explain ssrf
explain prints the rule and fixes in the terminal. It does not
use the network.