HIGH CWE-918 SSRF

CWE-918 in APIs

What is CWE-918?

CWE-918 (Server-Side Request Forgery - SSRF) is a critical web application vulnerability where an attacker can coerce a server into making unauthorized requests to internal or external resources. The weakness occurs when an application uses user-supplied URLs to make HTTP requests without proper validation or authorization.

The core problem: the server trusts its own network position and doesn't verify whether it should be accessing the requested resource. An attacker can leverage this trust to reach internal systems, bypass network controls, or access sensitive data.

According to the CWE description, this weakness exists when "the software does not properly control the redirection of a request to another location." This creates a scenario where malicious actors can manipulate URLs to target internal APIs, cloud metadata services, or external systems.

CWE-918 in API Contexts

APIs are particularly vulnerable to SSRF because they often need to make outbound requests as part of their functionality. Common API patterns that introduce SSRF risk include:

  • Webhook processing - accepting URLs where events should be sent
  • API aggregation - fetching data from user-provided endpoints
  • Image processing - downloading images from URLs for analysis
  • PDF generation - rendering web pages from URLs
  • Import/export functionality - reading data from external sources
  • Payment processing - communicating with external payment gateways

In API contexts, SSRF becomes more dangerous because APIs often have privileged network access. An API server might be able to reach internal databases, admin interfaces, or cloud provider metadata endpoints that contain credentials or configuration data.

Consider an API endpoint that accepts a URL parameter to fetch user profile pictures. If an attacker provides http://169.254.169.254/latest/meta-data/ (AWS metadata service), the API server might return sensitive instance information including IAM role credentials.

Detection

Detecting SSRF requires both static analysis and dynamic testing. Here's how to identify this weakness:

  • Code review - Look for HTTP client usage with user-supplied URLs, lack of URL validation, and absence of allowlist patterns
  • Network monitoring
  • Automated scanning - Use tools that can detect SSRF vulnerabilities by attempting controlled requests to known internal services

middleBrick's SSRF detection specifically tests for this weakness by attempting to access common internal endpoints and cloud metadata services. The scanner tries requests to:

  • Private IP ranges (10.x, 172.16-31.x, 192.168.x)
  • Localhost and loopback addresses
  • Cloud metadata endpoints (AWS, Azure, GCP)
  • Common internal service ports

The scanner reports whether the API server responds to these requests, indicating SSRF vulnerability. This black-box approach tests the actual runtime behavior without requiring source code access.

middleBrick also checks for proper URL validation by attempting protocol smuggling (file://, gopher://, ftp://) and testing whether the API properly handles different URL schemes.

Remediation

Fixing SSRF requires a defense-in-depth approach with multiple layers of validation:

1. URL Validation and Allowlisting

const validateUrl = (inputUrl, allowedDomains) => {
  try {
    const url = new URL(inputUrl);
    
    // Protocol allowlist
    if (!['http:', 'https:'].includes(url.protocol)) {
      throw new Error('Invalid protocol');
    }
    
    // Domain allowlist check
    const normalizedDomain = url.hostname.toLowerCase();
    if (!allowedDomains.includes(normalizedDomain)) {
      throw new Error('Domain not allowed');
    }
    
    // Private IP range detection
    const ip = url.hostname.split('.').map(Number);
    if (ip.length === 4) {
      if (
        (ip[0] === 10) ||
        (ip[0] === 172 && ip[1] >= 16 && ip[1] <= 31) ||
        (ip[0] === 192 && ip[1] === 168) ||
        (ip[0] === 127) ||
        (ip[0] === 169 && ip[1] === 254)
      ) {
        throw new Error('Private IP address not allowed');
      }
    }
    
    return url;
  } catch (error) {
    throw new Error(`Invalid URL: ${error.message}`);
  }
};

// Usage
const allowedDomains = ['trusted-api.com', 'cdn.example.com'];
const safeUrl = validateUrl(userProvidedUrl, allowedDomains);

2. Network-Level Controls

Implement network controls to prevent outbound requests to restricted destinations:

# iptables rules to block internal network access
iptables -A OUTPUT -d 10.0.0.0/8 -j DROP
iptables -A OUTPUT -d 172.16.0.0/12 -j DROP
iptables -A OUTPUT -d 192.168.0.0/16 -j DROP
iptables -A OUTPUT -d 127.0.0.0/8 -j DROP
iptables -A OUTPUT -d 169.254.0.0/16 -j DROP

3. Timeouts and Resource Limits

Always implement strict timeouts and resource limits:

const fetchWithLimits = async (url) => {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 5000); // 5 second timeout
  
  try {
    const response = await fetch(url, {
      signal: controller.signal,
      headers: { 'User-Agent': 'YourAppName/1.0' },
      compress: false
    });
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    
    return await response.text();
  } catch (error) {
    if (error.name === 'AbortError') {
      throw new Error('Request timeout');
    }
    throw error;
  } finally {
    clearTimeout(timeout);
  }
};

4. Content-Type Validation

Validate that responses match expected content types:

const validateContentType = async (url, expectedType) => {
  const response = await fetch(url, { method: 'HEAD' });
  const contentType = response.headers.get('content-type');
  
  if (!contentType || !contentType.startsWith(expectedType)) {
    throw new Error('Unexpected content type');
  }
  
  return response;
};

For comprehensive protection, combine these approaches. Use allowlisting for known-good domains, network controls for defense-in-depth, and always implement timeouts and content validation.

Frequently Asked Questions

How does middleBrick detect SSRF vulnerabilities?
middleBrick tests for SSRF by attempting controlled requests to known internal services and private IP ranges. The scanner tries to access cloud metadata endpoints (AWS, Azure, GCP), private IP addresses, and localhost. If the API server responds to these requests, middleBrick flags it as vulnerable. This black-box approach tests actual runtime behavior without requiring source code access, making it effective for identifying SSRF in production APIs.
Can SSRF lead to data breaches?
Yes, SSRF can lead to serious data breaches. Attackers can use SSRF to access internal APIs, cloud metadata services containing credentials, or backend databases. For example, AWS metadata endpoints often contain IAM role credentials that could provide full cloud access. SSRF can also be used to scan internal networks, access admin interfaces, or reach services that trust the internal network. This makes SSRF a critical vulnerability that requires immediate remediation.