Mobb User Docs
Start NowBlogsWatch NowContact Us
  • What is Mobb?
  • What's New with Mobb
  • Supported Fixes
  • Getting Started
    • System Requirements
    • Onboarding Guide
      • Registering a Mobb account
      • Try Mobb now!
      • Running Mobb against your own code
      • Automate Mobb in a CI/CD pipeline
    • Working with the Fix Report
    • Mobb CLI Overview
      • Analyze Mode
      • Scan Mode
      • Add SCM Token Mode
      • Review Mode
      • Common Deployment Scenarios
  • Mobb Dashboard
  • Integrating SAST Findings
    • Checkmarx
      • Generating Checkmarx One JSON Report from CLI
    • Snyk
    • SonarQube
      • Generating a SonarQube SAST Report
    • Fortify
    • CodeQL
    • Semgrep/Opengrep
      • Generating a Semgrep SAST Report
      • Generating an Opengrep SAST Report
  • CI/CD Integrations
    • GitHub Actions
      • GitHub Fixer for CxOne
      • GitHub Fixer for Opengrep
    • GitLab Pipeline
    • Azure DevOps
    • Jenkins
    • CircleCI
    • Bamboo
    • Bitbucket Pipeline
  • Administration
    • User Management
    • Project Settings
    • Access Tokens
    • Organization-Level Fix Policy
    • Integrations Page
    • SAML Single Sign-On Flow
  • More Info
    • Mobb Broker
      • Mobb Broker Token Rotation
      • Secure storage of Mobb broker in AWS Secrets Manager
    • Providing Fix Feedback
    • Frequently Asked Questions (FAQ)
    • Data Protection and Retention
    • Service Level Agreement
  • Fixing Guides
    • SQL Injection
    • Path Traversal
    • Log Forging
    • XSS
    • XXE
    • Server Side Request Forgery
    • HttpOnly Cookie Vulnerabilities
    • Hardcoded Domain in HTML
    • Hardcoded Secrets
    • HTTP Response Splitting Attacks
    • Insecure Cookie Vulnerabilities
    • Insecure Randomness
    • Missing Check against Null
    • Missing Rate Limiting
    • Regex Missing Timeout
    • System Information Leakage
  • Mobb REST API Guide
Powered by GitBook
On this page
  • What is SSRF and How Does it Work?
  • One Simple SSRF Attack Example
  • SSRF Prevention Methods: How to Fix Your Code
  • Code Samples
  • Need more help in preventing SSRF?
  • We'd love your feedback!

Was this helpful?

  1. Fixing Guides

Server Side Request Forgery

Learn how to prevent Server Side Request Forgery (SSRF) attacks with real code examples and best practices. Protect your application from SSRF vulnerabilities and security threats.

Tools recognizing this:

Opengrep Fortify Checkmarx SonarQube Snyk Semgrep CodeQL

What is SSRF and How Does it Work?

Server Side Request Forgery (SSRF) is a web security vulnerability that allows attackers to induce the server-side application to make requests to unintended locations. It occurs when an application accepts user-supplied URLs without proper validation, allowing attackers to manipulate the server into making malicious requests.

The attacker can potentially:

  • Access internal services behind firewalls

  • Scan internal networks

  • Interact with cloud service metadata endpoints

  • Execute remote code in some cases

  • Perform denial of service attacks

This guide covers SSRF attacks, examples, prevention methods, and how to test for SSRF vulnerabilities using real-world techniques.

One Simple SSRF Attack Example

Consider this classic example of a URL fetch:

String url = request.getParameter("url");
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();

An attacker could provide this input for the URL:

http://internal-service:8080/admin

The resulting request would attempt to access:

http://internal-service:8080/admin

This allows the attacker to access internal services that should not be publicly accessible.

SSRF Prevention Methods: How to Fix Your Code

The most efficient way to fix an SSRF issue in your code is implementing proper URL validation, including whitelisting allowed domains and blocking requests to internal networks.

URL validation should include checking the protocol, domain, and path against an allowlist of permitted values, and ensuring requests cannot be made to private IP ranges or internal hostnames.

Code Samples

Vulnerable Code

String url = request.getParameter("url");
URL obj = new URL();
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

Fixed Code

String url = request.getParameter("url");
if (!isUrlAllowed(url)) {
    throw new SecurityException("URL not allowed");
}
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

private boolean isUrlAllowed(String url) {
    List<String> allowedDomains = Arrays.asList("api.example.com", "cdn.example.com");
    try {
        URL u = new URL(url);
        return allowedDomains.contains(u.getHost()) && u.getProtocol().equals("https");
    } catch (MalformedURLException e) {
        return false;
    }
}

Fix Explanation

The vulnerable code accepts any URL without validation.The fix implements URL validation against a whitelist of allowed domains.Only HTTPS protocol is allowed.Timeouts are set to prevent hanging connections.

Vulnerable Code

const url = req.query.url;
const response = await fetch(url);
const data = await response.json();
res.send(data);

Fixed Code

const url = req.query.url;
const allowedDomains = ['api.example.com', 'cdn.example.com'];

function isUrlAllowed(urlString) {
    try {
        const urlObj = new URL(urlString);
        return allowedDomains.includes(urlObj.hostname) && 
               urlObj.protocol === 'https:';
    } catch {
        return false;
    }
}

if (!isUrlAllowed(url)) {
    throw new Error('URL not allowed');
}

const response = await fetch(url, {
    timeout: 5000,
    follow: 1
});
const data = await response.json();
res.send(data);

Fix Explanation

The vulnerable code makes requests to any provided URL.The fix validates URLs against a whitelist of allowed domains.Only HTTPS protocol is allowed.Request timeout and redirect limits are set.

Vulnerable Code

url = request.args.get('url')
response = requests.get(url)
return response.content

Fixed Code

from urllib.parse import urlparse
import requests

ALLOWED_DOMAINS = ['api.example.com', 'cdn.example.com']

def is_url_allowed(url):
    try:
        parsed = urlparse(url)
        return (parsed.scheme == 'https' and 
                parsed.netloc in ALLOWED_DOMAINS)
    except:
        return False

url = request.args.get('url')
if not is_url_allowed(url):
    raise ValueError('URL not allowed')

response = requests.get(url, 
                       timeout=5,
                       allow_redirects=False,
                       verify=True)
return response.content

Fix Explanation

The vulnerable code makes requests to any URL without validation.The fix implements URL validation with an allowed domains list.Only HTTPS is allowed.Timeouts and SSL verification are enforced.

Vulnerable Code

string url = Request.QueryString["url"];
using (var client = new HttpClient())
{
    var response = await client.GetAsync(url);
    return await response.Content.ReadAsStringAsync();
}

Fixed Code

private static readonly HashSet<string> AllowedDomains = 
    new HashSet<string> { "api.example.com", "cdn.example.com" };

private static bool IsUrlAllowed(string url)
{
    if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
    {
        return uri.Scheme == "https" && 
               AllowedDomains.Contains(uri.Host);
    }
    return false;
}

string url = Request.QueryString["url"];
if (!IsUrlAllowed(url))
{
    throw new SecurityException("URL not allowed");
}

using (var client = new HttpClient())
{
    client.Timeout = TimeSpan.FromSeconds(5);
    var response = await client.GetAsync(url);
    return await response.Content.ReadAsStringAsync();
}

Fix Explanation

The vulnerable code accepts any URL without validation.The fix implements URL validation against a whitelist.Only HTTPS URLs are allowed.Request timeout is configured.

Vulnerable Code

$url = $_GET['url'];
$content = file_get_contents($url);
echo $content;

Fixed Code

function isUrlAllowed($url) {
    $allowedDomains = ['api.example.com', 'cdn.example.com'];
    $parsed = parse_url($url);
    
    return isset($parsed['scheme']) && 
           $parsed['scheme'] === 'https' && 
           in_array($parsed['host'], $allowedDomains);
}

$url = $_GET['url'];
if (!isUrlAllowed($url)) {
    throw new Exception('URL not allowed');
}

$ctx = stream_context_create([
    'http' => [
        'timeout' => 5,
        'follow_location' => 0
    ]
]);

$content = file_get_contents($url, false, $ctx);
echo $content;

Fix Explanation

The vulnerable code fetches any provided URL.The fix validates URLs against an allowed domains list.Only HTTPS is allowed.Timeout and redirect settings are configured.

Vulnerable Code

url := r.URL.Query().Get("url")
resp, err := http.Get(url)
if err != nil {
    return err
}
io.Copy(w, resp.Body)

Fixed Code

var allowedDomains = map[string]bool{
    "api.example.com": true,
    "cdn.example.com": true,
}

func isUrlAllowed(urlStr string) bool {
    u, err := url.Parse(urlStr)
    if err != nil {
        return false
    }
    return u.Scheme == "https" && allowedDomains[u.Host]
}

url := r.URL.Query().Get("url")
if !isUrlAllowed(url) {
    return errors.New("URL not allowed")
}

client := &http.Client{
    Timeout: 5 * time.Second,
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
        return http.ErrUseLastResponse
    },
}

resp, err := client.Get(url)
if err != nil {
    return err
}
io.Copy(w, resp.Body)

Fix Explanation

The vulnerable code makes requests to any URL.The fix implements URL validation with allowed domains.Only HTTPS is allowed.Timeout and redirect policies are set.

Need more help in preventing SSRF?

We'd love your feedback!

We're excited to hear your thoughts and ideas about fixing vulnerabilities.

PreviousXXENextHttpOnly Cookie Vulnerabilities

Last updated 2 months ago

Was this helpful?

supports fixing many forms of SSRF vulnerabilities, and can mitigate your issues in batch.

Start now for free at

or if you have any corrections, questions or suggestions. Start now for free at https://app.mobb.ai

Mobb
app.mobb.ai
Book a meeting
Contact us