@@ -2235,6 +2235,58 @@ function apbct__is_wp_rocket_preloader_request()
22352235 );
22362236}
22372237
2238+ /**
2239+ * True for WordPress HTTP API loopback requests (Site Health, updates, cron).
2240+ * Default WP user-agent: "WordPress/{version}; {siteurl}"
2241+ *
2242+ * Requires both the WordPress UA prefix and that the URL in the UA belongs
2243+ * to this site. UA-only matching would skip Anti-Crawler for any spoofed
2244+ * WordPress client, including requests from other sites.
2245+ *
2246+ * Do not require REMOTE_ADDR === SERVER_ADDR: php-fpm loopbacks often arrive
2247+ * from the public origin IP while SERVER_ADDR is 127.0.0.1.
2248+ *
2249+ * @return bool
2250+ */
2251+ function apbct__is_wordpress_loopback_request ()
2252+ {
2253+ if ( ! isset ($ _SERVER ['HTTP_USER_AGENT ' ]) ) {
2254+ return false ;
2255+ }
2256+
2257+ if ( preg_match ('#^WordPress/\d[\d.]*;\s+(\S+)# ' , $ _SERVER ['HTTP_USER_AGENT ' ], $ matches ) !== 1 ) {
2258+ return false ;
2259+ }
2260+
2261+ $ ua_url = isset ($ matches [1 ]) ? $ matches [1 ] : '' ;
2262+ if ( $ ua_url === '' ) {
2263+ return false ;
2264+ }
2265+
2266+ $ ua_host = wp_parse_url ($ ua_url , PHP_URL_HOST );
2267+ if ( ! is_string ($ ua_host ) || $ ua_host === '' ) {
2268+ return false ;
2269+ }
2270+ $ ua_host = strtolower ($ ua_host );
2271+
2272+ $ site_hosts = array ();
2273+ foreach ( array (home_url (), site_url ()) as $ url ) {
2274+ $ host = wp_parse_url ($ url , PHP_URL_HOST );
2275+ if ( is_string ($ host ) && $ host !== '' ) {
2276+ $ site_hosts [] = strtolower ($ host );
2277+ }
2278+ }
2279+
2280+ if ( isset ($ _SERVER ['HTTP_HOST ' ]) ) {
2281+ $ host_header = preg_replace ('/:\d+$/ ' , '' , $ _SERVER ['HTTP_HOST ' ]);
2282+ if ( is_string ($ host_header ) && $ host_header !== '' ) {
2283+ $ site_hosts [] = strtolower ($ host_header );
2284+ }
2285+ }
2286+
2287+ return in_array ($ ua_host , $ site_hosts , true );
2288+ }
2289+
22382290/**
22392291 * Generates MD5 hash for email encoder pass key
22402292 *
0 commit comments