Server Side Request Forgery ('SSRF')

ID

php.server_side_request_forgery

Severity

critical

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Channel

Language

Php

Tags

ASVS50:v1.3.6, ASVS50:v13.2.5, CWE:918, NIST.SP.800-53, OWASP:2021:A10, PCI-DSS:6.5.8

Description

Improper validation of external input used to retrieve the content of a URL ('SSRF').

SSRF vulnerabilities arise when an application accepts user input to create or control URLs or networking requests without appropriate validation or restriction. This can allow attackers to craft malicious requests to sensitive internal endpoints or external services on behalf of the server.

Rationale

Similar to other injection attacks, an SSRF vulnerability allows an attacker to manipulate the URLs used by a server-side application, to point to unexpected internal or external resources.

By carefully selecting the URLs, the attacker can read or update internal resources, such as cloud metadata, internal services, or databases. In addition, SSRF can bypass network access controls like firewalls and VPNs.

An SSRF vulnerability can be exploited by threat actors for network reconnaissance, data exfiltration, denial of service or pivot attacks to other systems.

For instance, consider a PHP application that fetches resources based on user-provided URLs:

<?php
$url = $_GET['url']; // User-provided input
$response = file_get_contents($url); // Potentially dangerous
echo $response;
?>

Severity when the destination server is fixed

The severity in the table above applies when the external input can reach the destination of the request. When the URL is built from a constant prefix that already fixes the scheme, the host and the port, the input lands after the authority and can only choose a path or a query string, so the request cannot be steered to another server. The detector recognizes this and reports the finding at low severity instead.

With BASE a constant "https://api.internal.example.com", a URL built as BASE + "/" + target puts target in the path: it selects which endpoint of that fixed server is invoked, not which server is invoked.

The finding is lowered rather than dropped, because the input still decides which endpoint of that server runs and may reach operations that were not meant to be callable this way. A path is also not always inert: if the fixed host answers with a redirect, an HTTP client that follows redirects can still end up requesting a location the caller did not choose.

The severity is left unchanged whenever the input can still affect the destination:

  • it reaches the scheme, the host or the port - for example SCHEME + target + "/api", "https://" + tenant + ".example.com/api" or BASE + ":" + port + "/api";

  • the prefix does not close the authority, as in BASE + suffix, where the input can extend the host name into a different domain;

  • the prefix cannot be resolved to a constant - a value imported from another module, a parameter default, or a name that is assigned again after its declaration, is not treated as fixed;

  • the prefix does not describe a host that a URL could carry, one with an empty label say. That is not a URL anyone writes, it is what is left when part of the expression could not be resolved, and the part that could not be resolved is the one under external control.

It is also left unchanged when the fixed host is itself the sensitive target, because there choosing the path is the attack rather than a limitation of it: with a URL fixed to http://169.254.169.254/latest, the path selects which instance credentials are read. This covers cloud instance-metadata endpoints, loopback addresses, Kubernetes and cloud-internal service names, and private or otherwise reserved address ranges. The check is purely lexical, so a public host name that resolves to a private address at run time is not recognized.

Remediation

To prevent SSRF vulnerabilities in applications, follow these remediation practices:

  • Input Validation and Whitelisting: Always sanitize and validate user-supplied data in URLs using a whitelist of known, safe URLs. Reject any URLs not meeting established criteria to limit exposure to external or unauthorized internal requests.

  • Use a Proxy or Gateway Approach: Route all outbound requests through a proxy or gateway, allowing finer control over which requests should be allowed and logged.

  • Network Segmentation and Firewalls: Implement network segmentation to restrict the application’s ability to access sensitive internal services. Use firewalls to block traffic by default and allow only specific, necessary requests.

  • Monitoring and Logging: Implement comprehensive request logging and monitoring solutions to detect suspicious outbound requests indicative of SSRF attempts.

By following these recommended practices, applications can effectively defend against SSRF vulnerabilities, ensuring that server-side requests are controlled and properly secured from unauthorized exploitation.

A sanitized version of the previous example would look like this:

<?php
$trusted_domains = ['example.com', 'api.example.com'];
$url = $_GET['url'];
$parsed_url = parse_url($url);
$host = $parsed_url['host'];

if (in_array($host, $trusted_domains)) {
    $response = file_get_contents($url);
    echo $response;
} else {
    die('Invalid domain.');
}
?>

Configuration

The detector has the following configurable parameters:

  • sources, that indicates the source kinds to check.

  • neutralizations, that indicates the neutralization kinds to check.

Unless you need to change the default behavior, you typically do not need to configure this detector.

References

© 2026 Xygeni. All rights reserved