Ssrf Server Side in Express
How SSRF Manifests in Express Applications
Server-Side Request Forgery (SSRF) in Express applications occurs when an attacker can manipulate a server-side component to make HTTP requests to arbitrary destinations. In Express, this typically manifests through user-controlled input that gets passed directly to Node.js HTTP clients without proper validation.
The most common Express SSRF patterns involve request bodies, query parameters, or headers containing URLs that the server then fetches. For example:
app.post('/fetch', (req, res) => {
const url = req.body.url; // User-controlled URL
fetch(url) // SSRF vulnerability
.then(response => response.text())
.then(data => res.send(data))
.catch(err => res.status(500).send(err.message));
});This endpoint is vulnerable because any user can supply a URL to any internal service, external service, or cloud metadata endpoint. Attackers commonly target:
- Cloud metadata services (AWS: http://169.254.169.254/latest/meta-data/, Azure: http://169.254.169.254/metadata/instance?api-version=2021-01-01)
- Internal network services (192.168.x.x, 10.x.x.x, 172.16.x.x)
- Localhost services (http://localhost:8080, http://127.0.0.1:3000)
- External services for data exfiltration
Express-specific SSRF often appears in middleware chains where URL parameters flow through multiple handlers before being used. The asynchronous nature of Node.js can also lead to timing-based SSRF where responses are processed before validation completes.
Express-Specific Detection and Scanning
Detecting SSRF in Express requires both static code analysis and dynamic runtime testing. middleBrick's black-box scanning approach is particularly effective for Express applications since it tests the actual HTTP endpoints without requiring source code access.
middleBrick scans Express APIs by sending requests with SSRF payloads to identify vulnerable endpoints. The scanner tests for:
- Cloud metadata endpoint access (AWS, Azure, GCP metadata services)
- Internal network access patterns (RFC 1918 addresses, localhost)
- Protocol smuggling attempts (file://, gopher://, ftp://)
- DNS rebinding scenarios
- Port scanning capabilities
For Express applications, middleBrick's scanning is particularly effective because Express's predictable routing patterns and middleware structure create consistent attack surfaces. The scanner identifies endpoints that accept URL parameters, then systematically tests each with SSRF payloads.
Development teams can integrate SSRF detection into their Express workflow using the middleBrick CLI:
npm install -g middlebrick
middlebrick scan https://api.example.com --output jsonThe GitHub Action integration allows continuous SSRF monitoring in Express CI/CD pipelines:
- name: Scan for SSRF vulnerabilities
uses: middlebrick/middlebrick-action@v1
with:
target: https://staging-api.example.com
fail-on-severity: highmiddleBrick's LLM security scanning also detects SSRF in AI-powered Express endpoints that use model APIs or external service calls, a unique capability not found in other scanners.
Express-Specific SSRF Remediation
Remediating SSRF in Express requires a defense-in-depth approach using both input validation and network controls. The most effective Express-specific remediation combines URL validation with request whitelisting.
First, implement strict URL validation using a whitelist approach:
const { URL } = require('url');
const allowedDomains = ['api.example.com', 'trusted-service.com'];
function validateUrl(inputUrl) {
try {
const url = new URL(inputUrl);
// Block private IP ranges
const privateIpRanges = [
/^127\./, // localhost
/^10\./, // 10.0.0.0/8
/^172\.(1[6-9]|2[0-9]|3[0-1])\./, // 172.16.0.0/12
/^192\.168\./, // 192.168.0.0/16
/^169\.254\./, // Link-local
/^0\.0\.0\.0/, // Invalid address space
];
if (privateIpRanges.some(regex => regex.test(url.hostname))) {
return false;
}
// Block cloud metadata endpoints
if (url.hostname === '169.254.169.254' || url.hostname === '169.254.254.169') {
return false;
}
// Check allowed domains
if (!allowedDomains.includes(url.hostname)) {
return false;
}
// Block dangerous protocols
if (!['http:', 'https:'].includes(url.protocol)) {
return false;
}
return true;
} catch (err) {
return false;
}
}
app.post('/fetch', (req, res) => {
const url = req.body.url;
if (!validateUrl(url)) {
return res.status(400).json({ error: 'Invalid or blocked URL' });
}
fetch(url)
.then(response => response.text())
.then(data => res.send(data))
.catch(err => res.status(500).send(err.message));
});For Express applications using middleware, implement SSRF protection as reusable middleware:
function ssrfProtection(allowedDomains = []) {
return (req, res, next) => {
const urlParam = req.query.url || req.body.url;
if (urlParam && !validateUrl(urlParam)) {
return res.status(400).json({ error: 'URL blocked by SSRF protection' });
}
next();
};
}
// Apply to specific routes
app.post('/fetch', ssrfProtection(['api.example.com']), fetchHandler);
// Or apply globally to all routes
app.use(ssrfProtection());Network-level controls complement Express code fixes. Use firewall rules to block outbound connections to internal networks from your Express application servers. For cloud deployments, restrict instance metadata service access through IAM roles and network policies.
Express's built-in body parsing middleware helps by ensuring URL parameters are properly parsed before validation occurs. Always use express.json() and express.urlencoded() with appropriate size limits to prevent SSRF via oversized requests.