From 4b59647aef6a332ecc33ce24f76ff95a4d5a5a54 Mon Sep 17 00:00:00 2001 From: Andrew Shell Date: Wed, 8 Apr 2026 17:17:10 -0500 Subject: [PATCH] Normal subscribers require unsafe urls --- rsscloud/notification-request.php | 4 +-- rsscloud/send-post-notifications.php | 2 +- tests/test-notification-request.php | 40 ++++++++++++++++++++++++++ tests/test-send-post-notifications.php | 28 ++++++++++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/rsscloud/notification-request.php b/rsscloud/notification-request.php index bd3aeaa..b674c9c 100644 --- a/rsscloud/notification-request.php +++ b/rsscloud/notification-request.php @@ -50,12 +50,12 @@ function rsscloud_hub_process_notification_request( ) { $challenge = rsscloud_generate_challenge( ); - $result = wp_safe_remote_get( $notify_url . '?url=' . esc_url( wp_unslash( $_POST['url1'] ) ) . '&challenge=' . $challenge, array( 'method' => 'GET', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, ) ); + $result = wp_remote_get( $notify_url . '?url=' . esc_url( wp_unslash( $_POST['url1'] ) ) . '&challenge=' . $challenge, array( 'method' => 'GET', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, ) ); } else { if ( false === strpos( $notify_url, 'http://' ) ) $notify_url = 'http://' . $notify_url; - $result = wp_safe_remote_post( $notify_url, array( 'method' => 'POST', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, 'body' => array( 'url' => esc_url_raw( wp_unslash( $_POST['url1'] ) ) ) ) ); + $result = wp_remote_post( $notify_url, array( 'method' => 'POST', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, 'body' => array( 'url' => esc_url_raw( wp_unslash( $_POST['url1'] ) ) ) ) ); } if ( is_wp_error( $result ) ) diff --git a/rsscloud/send-post-notifications.php b/rsscloud/send-post-notifications.php index 63638ba..15b526e 100644 --- a/rsscloud/send-post-notifications.php +++ b/rsscloud/send-post-notifications.php @@ -30,7 +30,7 @@ function rsscloud_send_post_notifications( $rss2_url = false ) { if ( !empty( $url['port'] ) ) $port = $url['port']; - $result = wp_safe_remote_post( $notify_url, array( 'method' => 'POST', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, 'body' => array( 'url' => $rss2_url ) ) ); + $result = wp_remote_post( $notify_url, array( 'method' => 'POST', 'timeout' => RSSCLOUD_HTTP_TIMEOUT, 'user-agent' => RSSCLOUD_USER_AGENT, 'port' => $port, 'body' => array( 'url' => $rss2_url ) ) ); do_action( 'rsscloud_send_notification' ); diff --git a/tests/test-notification-request.php b/tests/test-notification-request.php index 26e18df..1e6f99c 100644 --- a/tests/test-notification-request.php +++ b/tests/test-notification-request.php @@ -534,4 +534,44 @@ function ( $preempt, $args, $url ) { $notify = rsscloud_get_hub_notifications(); $this->assertArrayHasKey( 'http://callback.example.com:9000/notify', $notify[ $this->feed_url ] ); } + + public function test_domain_based_nonstandard_port_not_rejected_by_url_validation() { + // No pre_http_request mock — let the real HTTP layer run so + // wp_http_validate_url is exercised. With a non-standard port, + // wp_safe_remote_get rejects the URL before any network call. + $_POST = array( + 'url1' => $this->feed_url, + 'port' => '4000', + 'path' => '/feedupdated', + 'domain' => 'web04.geekity.com', + ); + + $result = $this->call_process_notification_request(); + + // The request may fail for network reasons (e.g. connection refused), + // but it must NOT fail because of URL validation. + $this->assertStringNotContainsString( + 'A valid URL was not provided', + $result->msg, + 'Non-standard port should not be rejected by URL validation.' + ); + } + + public function test_ip_based_nonstandard_port_not_rejected_by_url_validation() { + // No pre_http_request mock — exercise real URL validation. + $_POST = array( + 'url1' => $this->feed_url, + 'protocol' => 'http-post', + 'port' => '4000', + 'path' => '/feedupdated', + ); + + $result = $this->call_process_notification_request(); + + $this->assertStringNotContainsString( + 'A valid URL was not provided', + $result->msg, + 'Non-standard port should not be rejected by URL validation.' + ); + } } diff --git a/tests/test-send-post-notifications.php b/tests/test-send-post-notifications.php index 62115b0..ffc7999 100644 --- a/tests/test-send-post-notifications.php +++ b/tests/test-send-post-notifications.php @@ -274,4 +274,32 @@ function () use ( &$fired ) { $this->assertTrue( $fired ); } + + public function test_nonstandard_port_not_rejected_by_url_validation() { + // Call the same function the plugin uses to send notifications, + // without mocking HTTP, to verify URL validation accepts non-standard ports. + $url = 'http://web04.geekity.com:4000/feedupdated'; + $result = wp_remote_post( + $url, + array( + 'method' => 'POST', + 'timeout' => 5, + 'user-agent' => RSSCLOUD_USER_AGENT, + 'port' => 4000, + 'body' => array( 'url' => $this->feed_url ), + ) + ); + + // The request may fail for network reasons, but must NOT fail + // due to URL validation rejecting the non-standard port. + if ( is_wp_error( $result ) ) { + $this->assertStringNotContainsString( + 'A valid URL was not provided', + $result->get_error_message(), + 'Non-standard port should not be rejected by URL validation.' + ); + } else { + $this->assertIsArray( $result ); + } + } }