← All advisories
high

Contributor-to-internal-network reflected SSRF proxy through URL details

Advisory ID
HKV-ADV-2026-027
Tracking ID
HKV-2026-027
Vendor
WordPress
Published

Summary

A Contributor can use the URL-details endpoint as a reflected server-side HTTP proxy. The supplied chain analysis combines the reflected metadata fields with the shared special-use IP validator gap and DNS-resolution TOCTOU. Reading internal services is demonstrated by the component report; broader network mapping and cloud metadata access depend on reachable services and configuration.

Affected Products

WordPress core URL-details REST endpoint. The readable vulnerability package documents the affected behavior against WordPress 7.0.3; the August 12 disclosure states that the findings were revalidated against 7.0.4, but the readable chain artifact does not include a complete 7.0.4 execution trace. Exact 7.0.4 status remains vendor-confirmation pending.

Affected Scope

Product
WordPress
Component
REST URL-details controller and shared HTTP URL validation
Affected function
WP_REST_URL_Details_Controller::parse_url_details(); permissions_check(); wp_http_validate_url()
Affected versions
WordPress 7.0.3 per the readable supplied chain package; 7.0.4 revalidation is stated in the August 12 disclosure but is not independently traceable in the readable artifact
Safe version
Not established; vendor fix confirmation pending
CWE
CWE-918

Technical Summary

Authenticated reflected SSRF for Contributor-level callers; the response returns selected metadata fetched from the attacker-supplied URL. The shared validator gap and DNS-rebinding TOCTOU expand the reachable destination set.

Prerequisites and Permissions

Contributor or higher with edit_posts; authenticated REST session and X-WP-Nonce; the route must be enabled and the site must be able to make outbound HTTP requests. Internal or cloud impact additionally requires a reachable target service.

Affected Locations

wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php: register_routes() URL argument and permissions_check() (reported around line 197); parse_url_details() and get_remote_url(); parameter url; wp-includes/http.php: wp_http_validate_url() shared validation path; default ports 80, 443, and 8080 are relevant in the supplied report.

Reproducible Proof

The supplied component report records a Contributor request to /wp-block-editor/v1/url-details?url=http://100.64.0.10:8080/ with an X-WP-Nonce. The response reflected title "SSRF-REFLECTED-INTERNAL-SECRET" and description "internal-metadata-body-leaked"; a listener log recorded the server-side GET. Full internal target lists, cloud-metadata paths, and DNS-rebinding timing are withheld.

Vulnerable Code

PHPsource excerpt
class="tok-comment">// class-wp-rest-url-details-controller.php
&class="tok-comment">#39;url' => array(
    &class="tok-comment">#39;required'          => true,
    &class="tok-comment">#39;validate_callbackclass="tok-string">' => 'wp_http_validate_url',
    &class="tok-comment">#39;sanitize_callbackclass="tok-string">' => 'sanitize_url',
    &class="tok-comment">#39;typeclass="tok-string">'              => 'string',
    &class="tok-comment">#39;formatclass="tok-string">'            => 'uri',
),

$response = wp_safe_remote_get( $url, $args );

$data = $this->add_additional_fields_to_object(
    array(
        &class="tok-comment">#39;title'       => $this->get_title( $html_head ),
        &class="tok-comment">#39;icon'        => $this->get_icon( $html_head, $url ),
        &class="tok-comment">#39;description' => $this->get_description( $meta_elements ),
        &class="tok-comment">#39;image'       => $this->get_image( $meta_elements, $url ),
    ),
    $request
);

Severity

high

Technical Analysis

WP_REST_URL_Details_Controller registers /wp-block-editor/v1/url-details with a required url parameter validated by wp_http_validate_url and permits callers with edit_posts. The controller fetches the attacker-supplied URL server-side through wp_safe_remote_get, parses the returned document, and reflects title, description, icon, and image metadata in JSON. The supplied report records the shared validator gap for 169.254.0.0/16 and 100.64.0.0/10 plus DNS-resolution time-of-check/time-of-use behavior. That turns the endpoint into a reflected read primitive rather than a blind request oracle.

Impact

Confidentiality: High for internal titles, descriptions, and Open Graph metadata; cloud metadata access is conditional on hosting and reachable services. Integrity: Not demonstrated. Availability: Not demonstrated. The chain requires a Contributor-level account with edit_posts and an outbound HTTP path to the target.

Remediation

Complete the reserved-range and CIDR validation in wp_http_validate_url, resolve and validate the destination immediately before connecting, and repeat the check after redirects. Restrict outbound requests at the network layer, review whether URL-details and related oEmbed fetches need to accept arbitrary destinations, and add regression tests for link-local, shared-address, DNS-rebinding, redirect, IPv6, and non-default-port cases.

Timeline

Credits

Aria Akhavan / Haikhavan Security