Hardening: allowed_redirect_hosts widening also relaxes core's SSRF guard for configured hosts #11

Closed
opened 2026-10-15 22:38:57 -07:00 by eric · 0 comments
Owner

Type: hardening (not a confirmed vulnerability). Found by security audit run 3 (commit 01195c8), observed in a local WordPress 7.1.3 lab.

What happens

RedirectGuard::filterAllowedHosts (src/Rewrite/RedirectGuard.php:60-69) adds every configured host to allowed_redirect_hosts. Core also consults that list from its outbound-request guard: the http_request_host_is_external filter calls wp_validate_redirect. As a result, any configured host that resolves to a private/internal IP becomes fetchable by wp_safe_remote_* (pingback source fetches, oEmbed discovery, etc.) on ports 80/443/8080.

Lab: with the plugin active, wp_http_validate_url() accepted http://example.test/, http://example.test:8080/ and http://<onion>/ (all resolving to a private 172.16.x address); with the plugin inactive core rejected all three.

Why it is only hardening

Reach is limited to admin-configured hosts, which by the plugin's contract are aliases of this same install, so no attacker-chosen destination is reachable. On multisite, though, a sub-site admin chooses the list (see #6).

Suggested fix

Either document this next to the existing allowed_redirect_hosts warning in the settings page/README, or scope the filter so it does not widen the SSRF check, e.g. skip adding hosts while http_request_host_is_external is running, or add only the current request host rather than every configured host.

**Type:** hardening (not a confirmed vulnerability). Found by security audit run 3 (commit `01195c8`), observed in a local WordPress 7.1.3 lab. ## What happens `RedirectGuard::filterAllowedHosts` (`src/Rewrite/RedirectGuard.php:60-69`) adds every configured host to `allowed_redirect_hosts`. Core also consults that list from its outbound-request guard: the `http_request_host_is_external` filter calls `wp_validate_redirect`. As a result, any configured host that resolves to a private/internal IP becomes fetchable by `wp_safe_remote_*` (pingback source fetches, oEmbed discovery, etc.) on ports 80/443/8080. Lab: with the plugin active, `wp_http_validate_url()` accepted `http://example.test/`, `http://example.test:8080/` and `http://<onion>/` (all resolving to a private 172.16.x address); with the plugin inactive core rejected all three. ## Why it is only hardening Reach is limited to admin-configured hosts, which by the plugin's contract are aliases of this same install, so no attacker-chosen destination is reachable. On multisite, though, a sub-site admin chooses the list (see #6). ## Suggested fix Either document this next to the existing allowed_redirect_hosts warning in the settings page/README, or scope the filter so it does not widen the SSRF check, e.g. skip adding hosts while `http_request_host_is_external` is running, or add only the current request host rather than every configured host.
eric closed this issue 2026-10-16 11:41:03 -07:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
eric/multi-domain-redux#11
No description provided.