How to Fix SSRF in Vibe-Coded Apps: A Practical Guide
OverMCP Team
Quick answer
SSRF (Server-Side Request Forgery) in vibe-coded apps happens when an AI-generated backend makes HTTP requests to URLs provided by user input without proper validation. This allows attackers to make your server fetch internal resources, like cloud metadata endpoints, leading to data breaches. Fix it by validating and allowlisting URLs, blocking private IP ranges, and using a robust SSRF protection library or service.
What is SSRF and why should vibe-coders care?
If you've built an app with Cursor, Bolt.new, or Replit Agent, you've likely used AI to generate code that fetches external URLs. Think of features like: a webhook that pulls data from a URL, an image proxy, a PDF generator that fetches remote resources, or a social media preview tool. AI tools are great at generating the happy path code, but they often skip security checks. SSRF is one of those silent killers that can turn your innocent feature into a gateway to your internal network.
In a vibe-coded app, SSRF vulnerabilities often come from AI generating code that directly uses user input in a fetch request without validation. For example, a simple endpoint like /fetch?url=... is a classic SSRF vector. Attackers can replace the URL with internal addresses like http://169.254.169.254/latest/meta-data/ (AWS metadata) or http://localhost:3000/admin to probe your internal services.
What to check first
Before you start fixing, audit your app for SSRF. Here's a checklist:
fetch( or axios.get( calls that use variables from request parameters, body, or headers.curl or Postman: send a request with url=http://169.254.169.254/latest/meta-data/ and see if you get a response.If you find any of these, you likely have an SSRF vulnerability.
Step-by-step fix
1. Validate and sanitize user input
Never trust user-supplied URLs. Start by validating the input is a valid URL and the scheme is http or https.
const url = new URL(input);
if (!['http:', 'https:'].includes(url.protocol)) {
throw new Error('Invalid protocol');
}2. Implement an allowlist for domains
If your app only needs to fetch from specific domains (e.g., api.example.com), allowlist them. This is the safest approach.
const allowedHosts = ['api.example.com', 'images.example.com'];
if (!allowedHosts.includes(url.hostname)) {
throw new Error('Host not allowed');
}3. Block private IP addresses and link-local ranges
Attackers can use DNS rebinding or redirects to bypass simple hostname checks. Resolve the hostname to an IP and verify it's not private or reserved.
const dns = require('dns').promises;
const ip = (await dns.lookup(url.hostname)).address;
if (isPrivateIP(ip)) {
throw new Error('Private IP blocked');
}
function isPrivateIP(ip) {
const parts = ip.split('.').map(Number);
if (parts[0] === 10) return true;
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true;
if (parts[0] === 192 && parts[1] === 168) return true;
if (parts[0] === 169 && parts[1] === 254) return true; // link-local
return false;
}4. Use a dedicated SSRF protection library
Consider using a library like ssrf-req-filter or axios-ssrf that handles these checks for you. For example, with ssrf-req-filter:
const { createClient } = require('ssrf-req-filter');
const client = createClient();
const response = await client.get(userUrl);5. Disable redirects or validate them
AI-generated code often follows redirects automatically. Attackers can use a redirect from an allowed domain to an internal IP. Disable redirects or validate each redirect target.
const response = await fetch(userUrl, { redirect: 'manual' });
if (response.status >= 300 && response.status < 400) {
const redirectUrl = new URL(response.headers.get('location'), userUrl);
// Re-validate redirectUrl with the same checks
}6. Use a network-level solution
If you're on a platform like Vercel, you can configure a proxy or use a serverless function that restricts outbound traffic. Some cloud providers offer VPC endpoints that block public internet access.
7. Run a security scan
After implementing fixes, run a security scan to catch any remaining issues. Tools like OverMCP's free AI app security scanner can automatically detect SSRF vulnerabilities and other common issues in vibe-coded apps. You can also use our continuous security monitoring to get alerts if new vulnerabilities appear.
Common mistakes
Vibe-coded apps often have these SSRF pitfalls:
::1 for localhost) are often overlooked. Make sure your IP blocking handles both IPv4 and IPv6.file://, gopher://, or dict:// can be dangerous.Real-world example
Imagine you built a social media dashboard that fetches a user-provided image URL to generate a preview. The AI-generated code might look like:
app.get('/preview', async (req, res) => {
const imageUrl = req.query.url;
const response = await fetch(imageUrl);
res.send(await response.buffer());
});This is a textbook SSRF. An attacker could request /preview?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ and steal your cloud credentials. The fix is to validate the URL, resolve the hostname, and check the IP, as shown earlier.
Beyond SSRF: Secure your vibe-coded app
SSRF is just one of many vulnerabilities that AI-generated code can introduce. To protect your app comprehensively, consider:
FAQ
What is SSRF in simple terms?
SSRF (Server-Side Request Forgery) is when an attacker tricks your server into making requests to unintended destinations, often internal or private network resources. It's like handing someone a phone and asking them to call a number, but they call your internal extension instead.
How do I know if my vibe-coded app has SSRF?
Look for any endpoint that takes a URL from user input and fetches it. Test it with a known internal IP like http://127.0.0.1 or http://169.254.169.254. If you get a response, you're vulnerable. Also, review your code for fetch or axios calls using unsanitized user input.
Can I fix SSRF without changing my app's architecture?
Yes, you can fix SSRF with proper input validation, IP blocking, and using libraries that handle these checks. For more robust protection, consider network-level controls like a firewall or a proxy that filters outbound requests. Tools like OverMCP can help you identify and fix these issues automatically.