[wp-trac] [WordPress Trac] #25840: Feature Request: WP_ACCESSIBLE_HOSTS as option

WordPress Trac noreply at wordpress.org
Thu Jan 22 14:53:11 UTC 2026


#25840: Feature Request: WP_ACCESSIBLE_HOSTS as option
-------------------------+-----------------------------
 Reporter:  xFireFartx   |       Owner:  (none)
     Type:  enhancement  |      Status:  new
 Priority:  normal       |   Milestone:  Future Release
Component:  HTTP API     |     Version:  3.7.1
 Severity:  normal       |  Resolution:
 Keywords:  has-patch    |     Focuses:
-------------------------+-----------------------------
Changes (by ozgursar):

 * keywords:  has-patch needs-testing => has-patch


Comment:

 == Test Report
 === Description
 This report validates whether the indicated patch works as expected.

 Patch tested: https://github.com/WordPress/wordpress-develop/pull/9824

 === Environment
 - WordPress: 7.0-alpha-61215-src
 - PHP: 8.2.29
 - Server: nginx/1.29.4
 - Database: mysqli (Server: 8.4.7 / Client: mysqlnd 8.2.29)
 - Browser: Chrome 144.0.0.0
 - OS: macOS
 - Theme: Twenty Twenty-One 2.7
 - MU Plugins: None activated
 - Plugins:
   * Code Snippets 3.9.4
   * Test Reports 1.2.1

 === Steps to Reproduce
 1. Add the following code via Code Snippets plugin, via your functions.php
 or install it as a plugin.


 {{{
 /**
  * Plugin Name: Test wp_accessible_hosts Filter & Backwards Compatibility
  * Description: Tests the new wp_accessible_hosts filter,
 WP_ACCESSIBLE_HOSTS constant backwards compatibility, and makes real API
 calls
  * Version: 2.0
  * Author: Filter Tester
  */

 // Add our test hosts via the new filter if it exists
 add_filter( 'wp_http_accessible_hosts', function ( $hosts ) {

     if ( ! is_array( $hosts ) ) {
         $hosts = [];
     }

     $hosts[] = 'jsonplaceholder.typicode.com';
     $hosts[] = 'api.github.com';

     return $hosts;

 }, 10, 1 );

 add_action( 'admin_notices', 'test_wp_accessible_hosts_comprehensive' );

 function test_wp_accessible_hosts_comprehensive() {
     // Check if external requests are blocked
     $external_blocked = defined( 'WP_HTTP_BLOCK_EXTERNAL' ) &&
 WP_HTTP_BLOCK_EXTERNAL;

     // Check if the constant is defined
     $constant_defined = defined( 'WP_ACCESSIBLE_HOSTS' );
     $constant_value = $constant_defined ? WP_ACCESSIBLE_HOSTS : 'Not
 defined';

     // Check if the filter exists in the code
     $http_file = ABSPATH . 'wp-includes/class-wp-http.php';
     $filter_in_code = false;
     $filter_lines = array();

     if ( file_exists( $http_file ) ) {
         $content = file_get_contents( $http_file );
         $filter_in_code = strpos( $content, 'wp_accessible_hosts' ) !==
 false;

         if ( $filter_in_code ) {
             $lines = explode( "\n", $content );
             foreach ( $lines as $line_num => $line ) {
                 if ( strpos( $line, 'wp_accessible_hosts' ) !== false ) {
                     $filter_lines[] = array(
                         'num' => $line_num + 1,
                         'content' => trim( $line )
                     );
                 }
             }
         }
     }

     // Check if filter has callbacks
     $has_callbacks = has_filter( 'wp_accessible_hosts' );

     // Test applying the filter
     $test_hosts = array( 'example.com' );
     $filtered_hosts = apply_filters( 'wp_accessible_hosts', $test_hosts );

     // Perform real API tests
     $api_test_results = array();

     // Test 1: JSONPlaceholder API (should work with our filter)
     $api_test_results['jsonplaceholder'] = test_api_call(
 'https://jsonplaceholder.typicode.com/posts/1' );

     // Test 2: GitHub API (should work with our filter)
     $api_test_results['github'] = test_api_call(
 'https://api.github.com/zen' );

     // Test 3: Random API that's not whitelisted (should fail if blocking
 is enabled)
     $api_test_results['httpbin'] = test_api_call(
 'https://httpbin.org/get' );

     ?>
     <div class="notice notice-info" style="padding: 15px;">
         <h2 style="margin-top: 0;">🔍 wp_accessible_hosts Filter &
 Backwards Compatibility Test</h2>

         <!-- Configuration Status -->
         <h3>📋 Current Configuration</h3>
         <table class="widefat" style="max-width: 900px; background: white;
 margin-bottom: 20px;">
             <thead>
                 <tr>
                     <th>Setting</th>
                     <th>Status</th>
                     <th>Details</th>
                 </tr>
             </thead>
             <tbody>
                 <tr>
                     <td><strong>WP_HTTP_BLOCK_EXTERNAL</strong></td>
                     <td><?php echo $external_blocked ? '🔴 Enabled
 (Blocking)' : '🟢 Disabled (Allowing All)'; ?></td>
                     <td>
                         <?php echo $external_blocked ? 'External requests
 are being blocked' : 'All external requests allowed'; ?>
                         <?php if ( ! $external_blocked ) : ?>
                             <br><strong style="color: #996800;">⚠️ NOTE:
 WP_ACCESSIBLE_HOSTS and wp_accessible_hosts filter have NO EFFECT when
 blocking is disabled!</strong>
                         <?php endif; ?>
                     </td>
                 </tr>
                 <tr>
                     <td><strong>WP_ACCESSIBLE_HOSTS constant</strong></td>
                     <td><?php echo $constant_defined ? '✅ Defined' : '❌
 Not Defined'; ?></td>
                     <td>
                         <code><?php echo esc_html( $constant_value );
 ?></code>
                         <?php if ( $constant_defined && !
 $external_blocked ) : ?>
                             <br><span style="color: #996800;">⚠️ This
 constant is ignored because WP_HTTP_BLOCK_EXTERNAL is false</span>
                         <?php endif; ?>
                     </td>
                 </tr>
             </tbody>
         </table>

         <!-- Live API Tests -->
         <h3>Live API Request Tests</h3>
         <p style="background: #e7f5fe; padding: 10px; border-left: 4px
 solid #2271b1; margin-bottom: 10px;">
             <strong>💡 KEY CONCEPT:</strong> These tests make <strong>real
 wp_remote_get() calls</strong> through WordPress core's HTTP class.
             If the patch is applied, WordPress will apply the
 <code>wp_accessible_hosts</code> filter during these requests.
         </p>
         <table class="widefat" style="max-width: 900px; background: white;
 margin-bottom: 20px;">
             <thead>
                 <tr>
                     <th>API</th>
                     <th>URL</th>
                     <th>Result</th>
                     <th>Details</th>
                 </tr>
             </thead>
             <tbody>
                 <tr>
 <td><strong>JSONPlaceholder</strong><br><small>(whitelisted via
 filter)</small></td>
                     <td><code style="font-size:
 11px;">jsonplaceholder.typicode.com</code></td>
                     <td><?php echo format_api_result(
 $api_test_results['jsonplaceholder'] ); ?></td>
                     <td>
                         <?php if (
 $api_test_results['jsonplaceholder']['success'] ) : ?>
                             <details>
                                 <summary style="cursor: pointer; color:
 #2271b1;">Show response</summary>
                                 <pre style="font-size: 11px; max-height:
 150px; overflow-y: auto; background: #f6f7f7; padding: 10px; margin-top:
 5px;"><?php echo esc_html( substr(
 $api_test_results['jsonplaceholder']['body'], 0, 500 ) ); ?></pre>
                             </details>
                         <?php else : ?>
                             <span style="color: #d63638;"><?php echo
 esc_html( $api_test_results['jsonplaceholder']['message'] ); ?></span>
                         <?php endif; ?>
                     </td>
                 </tr>
                 <tr>
                     <td><strong>GitHub API</strong><br><small>(whitelisted
 via filter)</small></td>
                     <td><code style="font-size:
 11px;">api.github.com</code></td>
                     <td><?php echo format_api_result(
 $api_test_results['github'] ); ?></td>
                     <td>
                         <?php if ( $api_test_results['github']['success']
 ) : ?>
                             <?php if ( $external_blocked &&
 $filter_in_code ) : ?>
                                 <span style="color: #00a32a; font-weight:
 bold;">✅ FILTER IS WORKING IN CORE!</span><br>
                                 <small>This API is ONLY whitelisted via
 the filter (not in constant), and it succeeded!</small>
                             <?php elseif ( $external_blocked && !
 $filter_in_code ) : ?>
                                 <span style="color: #996800; font-weight:
 bold;">⚠️ Unexpected Success</span><br>
                                 <small>Blocking is enabled but filter not
 in core - this shouldn't work!</small>
                             <?php else : ?>
                                 <span style="color: #00a32a;">Success
 (blocking disabled)</span>
                             <?php endif; ?>
                             <details>
                                 <summary style="cursor: pointer; color:
 #2271b1;">Show response</summary>
                                 <pre style="font-size: 11px; background:
 #f6f7f7; padding: 10px; margin-top: 5px;"><?php echo esc_html(
 $api_test_results['github']['body'] ); ?></pre>
                             </details>
                         <?php else : ?>
                             <?php if ( $external_blocked && !
 $filter_in_code ) : ?>
                                 <span style="color: #d63638; font-weight:
 bold;">✅ EXPECTED FAILURE</span><br>
                                 <small>Filter not in core, so this API
 should be blocked. This confirms the patch is NOT applied.</small>
                             <?php else : ?>
                                 <span style="color: #d63638;"><?php echo
 esc_html( $api_test_results['github']['message'] ); ?></span>
                             <?php endif; ?>
                         <?php endif; ?>
                     </td>
                 </tr>
                 <tr>
                     <td><strong>HTTPBin</strong><br><small>(NOT
 whitelisted)</small></td>
                     <td><code style="font-size:
 11px;">httpbin.org</code></td>
                     <td><?php echo format_api_result(
 $api_test_results['httpbin'] ); ?></td>
                     <td>
                         <?php if ( $api_test_results['httpbin']['success']
 ) : ?>
                             <span style="color: #00a32a;">Request
 succeeded (blocking not enabled or filter working)</span>
                         <?php else : ?>
                             <span style="color: #996800;">Expected: should
 be blocked if WP_HTTP_BLOCK_EXTERNAL is true</span>
                         <?php endif; ?>
                     </td>
                 </tr>
             </tbody>
         </table>

     </div>
     <?php
 }

 /**
  * Make a test API call
  */
 function test_api_call( $url ) {
     $response = wp_remote_get( $url, array(
         'timeout' => 5,
         'sslverify' => true,
     ) );

     if ( is_wp_error( $response ) ) {
         return array(
             'success' => false,
             'message' => $response->get_error_message(),
             'body' => ''
         );
     }

     $response_code = wp_remote_retrieve_response_code( $response );
     $body = wp_remote_retrieve_body( $response );

     return array(
         'success' => $response_code >= 200 && $response_code < 300,
         'message' => 'HTTP ' . $response_code,
         'body' => $body,
         'code' => $response_code
     );
 }

 /**
  * Format API result for display
  */
 function format_api_result( $result ) {
     if ( $result['success'] ) {
         return '<span style="color: #00a32a; font-weight: bold;">✅
 Success</span><br><small>HTTP ' . $result['code'] . '</small>';
     } else {
         return '<span style="color: #d63638; font-weight: bold;">❌
 Failed</span><br><small>' . esc_html( $result['message'] ) . '</small>';
     }
 }
 }}}


 2. Check WP Dashboard home to view the patch implementation results.

 === Actual Results
 1. ✅ Issue resolved with patch.
 2. ❌ Without patch applied, allowed hosts via filter are not reachable
 (e.g. jsonplaceholder.typicode.com and api.github.com in this case. Change
 them in the plugin file for your test case.)
 4. ✅ When patch applied, hosts allowed via filter are reachable. See
 screenshots below for example outputs and actual http response from the
 jsonplaceholder.typicode.com API.


 === Additional Notes
 - To be able to test the patch, add wp-config.php and add the following
 lines:

 {{{
 define( 'WP_HTTP_BLOCK_EXTERNAL', true );
 define( 'WP_ACCESSIBLE_HOSTS', 'example.com' );

 }}}

 - Defining only `WP_HTTP_BLOCK_EXTERNAL` is not enough. Filter works only
 if `WP_ACCESSIBLE_HOSTS` is defined and at least set to an empty string.

 - When I use the filter, I received the following PHP warning:
 `Warning: Undefined variable $w_accessible_hosts in /var/www/src/wp-
 includes/class-wp-http.php`


 === Supplemental Artifacts
 Before:
 [[Image(https://i.imgur.com/ICPpur8.png)]]

 After:
 [[Image(https://i.imgur.com/vuIMR9r.png)]]

 Example response from jsonplaceholder.typicode.com
 [[Image(https://i.imgur.com/N6Tlrzq.png)]]

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/25840#comment:18>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list