When a WordPress site sends an HTTP request to an arbitrary web address, such as fetching oEmbed data or pingbacks, it can risk Server-Side Request Forgery (SSRF). Without checks, outbound requests could reach internal networks, loopback addresses, or cloud metadata endpoints.
The WordPress HTTP API provides two functions to reduce these risks for outbound GET requests: wp_safe_remote_get() and wp_http_validate_url(). Together, they validate protocols, check host syntax, resolve hostnames to IPv4 addresses, block reserved IPv4 ranges, limit destination ports, and re-check redirect targets.
How wp_safe_remote_get Restricts Arbitrary GET Requests
The wp_safe_remote_get() function is designed for HTTP requests to arbitrary URLs. Under the hood, it forces URL safety validation by modifying request arguments:
function wp_safe_remote_get( $url, $args = array() ) {
$args['reject_unsafe_urls'] = true;
$http = _wp_http_get_object();
return $http->get( $url, $args );
}
Setting $args['reject_unsafe_urls'] = true instructs the HTTP transport layer to validate both the initial request URL and subsequent redirect locations against wp_http_validate_url(). If validation fails at any point, the request fails and returns a WP_Error object instead of completing the connection.
The URL Validation Checks in wp_http_validate_url
The wp_http_validate_url() function accepts a URL string and returns the original URL string if valid, or false if it fails security checks. It applies the following checks in order:
1. Protocol and Host String Validation
The function first examines basic string formatting and scheme requirements:
- Data type check: The value must be a non-empty string and not purely numeric.
- Allowed protocols: The URL is verified with
wp_kses_bad_protocol(), allowing onlyhttpandhttps. Protocols such asftp://orfile://returnfalse. - Host and credentials: The URL is parsed with PHP’s
parse_url(). Requests containing authentication credentials (userorpass) are rejected. If the hostname contains any of the characters:#?[], validation fails.
2. Destination IPv4 Address Filtering
If the host does not match the host configured in get_option( 'home' ), WordPress inspects its destination IP address:
- IP detection and DNS resolution: If the host is an IPv4 address string matching four octets, it is used directly. Otherwise, it is resolved via PHP’s
gethostbyname(). If DNS resolution fails, the function returnsfalse. - Reserved range checks: The resolved IPv4 address is split into octets and evaluated against reserved and private ranges defined by IANA and RFC standards. By default, requests resolving to the following IPv4 ranges return
false:
| IPv4 Address Range / CIDR | Designation or Purpose |
|---|---|
0.0.0.0/8 |
This network |
10.0.0.0/8 |
Private network (RFC 1918) |
100.64.0.0/10 |
Carrier-Grade NAT (RFC 6598) |
127.0.0.0/8 |
Loopback addresses |
169.254.0.0/16 |
Link-local and cloud metadata endpoints |
172.16.0.0/12 |
Private network (172.16.0.0 to 172.31.255.255) |
192.0.0.0/24 |
IETF protocol assignments |
192.0.2.0/24 |
TEST-NET-1 documentation |
192.88.99.0/24 |
6to4 relay anycast |
192.168.0.0/16 |
Private network (RFC 1918) |
198.18.0.0/15 |
Benchmark testing |
198.51.100.0/24 |
TEST-NET-2 documentation |
203.0.113.0/24 |
TEST-NET-3 documentation |
224.0.0.0/4 |
Multicast address assignments |
240.0.0.0/4 |
Reserved address space (including broadcast 255.255.255.255) |
3. Port Restrictions
If the URL includes an explicit port number, wp_http_validate_url() checks it against an allowed list. By default, only three ports are permitted:
- Port
80 - Port
443 - Port
8080
If the requested host matches the site’s configured home URL and uses the configured home port, that port is also accepted. Any other explicit destination port causes the function to return false.
Filter Hooks and Boundary Limitations
WordPress provides two filter hooks inside wp_http_validate_url() to adjust validation behavior:
http_request_host_is_external
apply_filters( 'http_request_host_is_external', bool $external, string $host, string $url )
When a host resolves to one of the reserved IPv4 ranges, this filter runs with $external set to false. Returning true allows the request to proceed. Because this bypasses private and loopback IP blocking, developers should scope callbacks strictly to expected hostnames or URLs rather than returning true globally, which would disable private IP protection across the site.
http_allowed_safe_ports
apply_filters( 'http_allowed_safe_ports', array( 80, 443, 8080 ), string $host, string $url )
This filter modifies the array of integer ports permitted by WordPress. Broadening the permitted ports allows requests to reach services running on alternate ports, so custom additions should be limited only to specific verified remote destinations.
Redirect Re-Validation
HTTP redirects can be leveraged to target internal addresses after providing an initial external URL. When reject_unsafe_urls is set to true by wp_safe_remote_get(), WordPress validates each redirected target URL via wp_http_validate_url() before making subsequent requests. If an external URL redirects to an address in a reserved IPv4 range (such as 127.0.0.1 or 169.254.169.254) or a disallowed port, the redirect chain is aborted.

Text version of the diagrams
- Safe GET vs URL Validator: Safe GET — Enables unsafe-URL rejection; URL checks — Validates scheme, host, port; Redirect checks — Revalidates each target
- Protection Boundaries: IPv4 ranges — Blocks reserved destinations; Safe ports — Allows 80, 443, 8080; Boundaries — IPv6 and app controls remain
Research Method and Limitations
This article was prepared directly from public WordPress developer documentation excerpts for wp_http_validate_url() and wp_safe_remote_get() retrieved on 2026-09-17. Competing coverage was unavailable for comparison. The documented checks represent an IPv4-focused defensive mechanism rather than a complete SSRF mitigation strategy; the visible primary excerpts do not define IPv6 range filtering or higher-level application controls. Furthermore, custom filter callbacks can override these protections if not narrowly restricted.



