From b89bec6500bd2a31f72069b98b91c7594e033c8a Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Tue, 30 Dec 2025 10:57:01 +0700 Subject: [PATCH 1/7] HTTP API: Early filter invalid hosts in wp_http_validate_url() --- src/wp-includes/http.php | 9 +++++++++ tests/phpunit/tests/http/http.php | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/wp-includes/http.php b/src/wp-includes/http.php index b343bb69f572b..c13d0d396752c 100644 --- a/src/wp-includes/http.php +++ b/src/wp-includes/http.php @@ -589,6 +589,15 @@ function wp_http_validate_url( $url ) { $host = trim( $parsed_url['host'], '.' ); if ( ! $same_host ) { + if ( + function_exists( 'filter_var' ) + && defined( 'FILTER_VALIDATE_DOMAIN' ) + && defined( 'FILTER_FLAG_HOSTNAME' ) + && ! filter_var( $host, FILTER_VALIDATE_IP ) + && ! filter_var( $host, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME ) + ) { + return false; + } if ( preg_match( '#^(([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)$#', $host ) ) { $ip = $host; } else { diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index 651064dc5674c..86b4fbb81a2ad 100644 --- a/tests/phpunit/tests/http/http.php +++ b/tests/phpunit/tests/http/http.php @@ -566,6 +566,9 @@ public function data_wp_http_validate_url_should_not_validate() { 'url' => 'https://example.com:81/caniload.php', 'cb_safe_ports' => 'callback_remove_safe_ports', ), + 'underscore_in_hostname' => array( + 'url' => 'https://foo_bar.example.com/', + ), ); } From 1439d456c33f1ee5134a08acd31f912b58af194f Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Tue, 30 Dec 2025 11:58:10 +0700 Subject: [PATCH 2/7] Validate non-IP hostnames early in wp_http_validate_url --- src/wp-includes/http.php | 19 +++++++++++++------ tests/phpunit/tests/http/http.php | 4 ++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/http.php b/src/wp-includes/http.php index c13d0d396752c..3d94521eaeabf 100644 --- a/src/wp-includes/http.php +++ b/src/wp-includes/http.php @@ -589,16 +589,23 @@ function wp_http_validate_url( $url ) { $host = trim( $parsed_url['host'], '.' ); if ( ! $same_host ) { + $is_ipv4 = (bool) preg_match( + '#^(([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)$#', + $host + ); + if ( - function_exists( 'filter_var' ) - && defined( 'FILTER_VALIDATE_DOMAIN' ) - && defined( 'FILTER_FLAG_HOSTNAME' ) - && ! filter_var( $host, FILTER_VALIDATE_IP ) - && ! filter_var( $host, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME ) + ! $is_ipv4 + && function_exists( 'filter_var' ) + && ! filter_var( + $host, + FILTER_VALIDATE_DOMAIN, + array( 'flags' => FILTER_FLAG_HOSTNAME ) + ) ) { return false; } - if ( preg_match( '#^(([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)$#', $host ) ) { + if ( $is_ipv4 ) { $ip = $host; } else { $ip = gethostbyname( $host ); diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index 86b4fbb81a2ad..e3f18d4d27f89 100644 --- a/tests/phpunit/tests/http/http.php +++ b/tests/phpunit/tests/http/http.php @@ -566,8 +566,8 @@ public function data_wp_http_validate_url_should_not_validate() { 'url' => 'https://example.com:81/caniload.php', 'cb_safe_ports' => 'callback_remove_safe_ports', ), - 'underscore_in_hostname' => array( - 'url' => 'https://foo_bar.example.com/', + 'underscore_in_hostname' => array( + 'url' => 'https://foo_bar.example.com/', ), ); } From fc38d7ab7e1f25d6af1ff59696dcf39cbd3b9b62 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Tue, 30 Dec 2025 14:36:27 +0700 Subject: [PATCH 3/7] HTTP: Early reject invalid hostnames in wp_http_validate_url() --- src/wp-includes/http.php | 2 +- tests/phpunit/tests/http/http.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/http.php b/src/wp-includes/http.php index 3d94521eaeabf..c1bf29f41ddbf 100644 --- a/src/wp-includes/http.php +++ b/src/wp-includes/http.php @@ -596,7 +596,7 @@ function wp_http_validate_url( $url ) { if ( ! $is_ipv4 - && function_exists( 'filter_var' ) + && extension_loaded( 'filter' ) && ! filter_var( $host, FILTER_VALIDATE_DOMAIN, diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index e3f18d4d27f89..2215514fc78dc 100644 --- a/tests/phpunit/tests/http/http.php +++ b/tests/phpunit/tests/http/http.php @@ -569,6 +569,9 @@ public function data_wp_http_validate_url_should_not_validate() { 'underscore_in_hostname' => array( 'url' => 'https://foo_bar.example.com/', ), + 'valid_ip_host' => array( + 'url' => 'https://1.1.1.1/', + ), ); } From 6c7eccb4851544fc6c11a5c6dcc17b8256461777 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Tue, 30 Dec 2025 14:56:01 +0700 Subject: [PATCH 4/7] Tests: fix inline alignment to satisfy PHPCS --- tests/phpunit/tests/http/http.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index 2215514fc78dc..46fc849125609 100644 --- a/tests/phpunit/tests/http/http.php +++ b/tests/phpunit/tests/http/http.php @@ -566,11 +566,11 @@ public function data_wp_http_validate_url_should_not_validate() { 'url' => 'https://example.com:81/caniload.php', 'cb_safe_ports' => 'callback_remove_safe_ports', ), - 'underscore_in_hostname' => array( - 'url' => 'https://foo_bar.example.com/', + 'underscore_in_hostname' => array( + 'url' => 'https://foo_bar.example.com/', ), - 'valid_ip_host' => array( - 'url' => 'https://1.1.1.1/', + 'valid_ip_host' => array( + 'url' => 'https://1.1.1.1/', ), ); } From d8d86bdf824fbf375d6bd787642ea256d49cdb14 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Tue, 30 Dec 2025 15:13:15 +0700 Subject: [PATCH 5/7] Tests: remove duplicate IP case and fix array formatting --- tests/phpunit/tests/http/http.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index 46fc849125609..86b4fbb81a2ad 100644 --- a/tests/phpunit/tests/http/http.php +++ b/tests/phpunit/tests/http/http.php @@ -566,11 +566,8 @@ public function data_wp_http_validate_url_should_not_validate() { 'url' => 'https://example.com:81/caniload.php', 'cb_safe_ports' => 'callback_remove_safe_ports', ), - 'underscore_in_hostname' => array( - 'url' => 'https://foo_bar.example.com/', - ), - 'valid_ip_host' => array( - 'url' => 'https://1.1.1.1/', + 'underscore_in_hostname' => array( + 'url' => 'https://foo_bar.example.com/', ), ); } From aa5990c17e7625a8498f35d4d04b7e135fad6625 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Tue, 30 Dec 2025 15:22:14 +0700 Subject: [PATCH 6/7] Tests: fix array alignment for PHPCS --- tests/phpunit/tests/http/http.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index 86b4fbb81a2ad..e5acd3a518982 100644 --- a/tests/phpunit/tests/http/http.php +++ b/tests/phpunit/tests/http/http.php @@ -566,7 +566,7 @@ public function data_wp_http_validate_url_should_not_validate() { 'url' => 'https://example.com:81/caniload.php', 'cb_safe_ports' => 'callback_remove_safe_ports', ), - 'underscore_in_hostname' => array( + 'underscore_in_hostname' => array( 'url' => 'https://foo_bar.example.com/', ), ); From fe877fdea07f0cda13b8ecdc233ba0958d19a5b2 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Wed, 31 Dec 2025 09:39:13 +0700 Subject: [PATCH 7/7] HTTP: compute IPv4 host earlier --- src/wp-includes/http.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/http.php b/src/wp-includes/http.php index c1bf29f41ddbf..defb13249e3a4 100644 --- a/src/wp-includes/http.php +++ b/src/wp-includes/http.php @@ -587,13 +587,12 @@ function wp_http_validate_url( $url ) { $parsed_home = parse_url( get_option( 'home' ) ); $same_host = isset( $parsed_home['host'] ) && strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] ); $host = trim( $parsed_url['host'], '.' ); + $is_ipv4 = (bool) preg_match( + '#^(([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)$#', + $host + ); if ( ! $same_host ) { - $is_ipv4 = (bool) preg_match( - '#^(([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)$#', - $host - ); - if ( ! $is_ipv4 && extension_loaded( 'filter' )