$xmlrpc_url, ); // Check if xmlrpc.php core file exists in WordPress root. $xmlrpc_file = \trailingslashit( ABSPATH ) . 'xmlrpc.php'; if ( ! \file_exists( $xmlrpc_file ) ) { return static::pass( __( 'The XML-RPC file has been removed from your site. This prevents a common attack vector.', '0-day-analytics' ), $details ); } // Check if XML-RPC is disabled via filter. // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Using WordPress core filter. $xmlrpc_enabled = \apply_filters( 'xmlrpc_enabled', true ); $details['filter_enabled'] = $xmlrpc_enabled; if ( ! $xmlrpc_enabled ) { return static::pass( __( 'XML-RPC is disabled via a filter. This protects against brute force and DDoS attacks that target this feature.', '0-day-analytics' ), $details ); } // Try to access XML-RPC endpoint. $response = \wp_remote_post( $xmlrpc_url, array( 'timeout' => 5, 'sslverify' => false, 'body' => 'system.listMethods', 'headers' => array_merge( array( 'Content-Type' => 'text/xml' ), Scanner::get_loopback_headers() ), ) ); if ( \is_wp_error( $response ) ) { return static::info( __( 'We couldn\'t check if XML-RPC is accessible. It may be blocked by your server or firewall.', '0-day-analytics' ), $details ); } $code = \wp_remote_retrieve_response_code( $response ); $body = \wp_remote_retrieve_body( $response ); $details['response_code'] = $code; // 403 or 405 means blocked. if ( in_array( $code, array( 403, 405 ), true ) ) { return static::pass( __( 'XML-RPC is blocked by your server or security plugin. This protects against brute force attacks.', '0-day-analytics' ), $details ); } // 200 with XML response means it's working. if ( 200 === $code && strpos( $body, 'WP Panel module (Security & API section) to disable XML-RPC', '0-day-analytics' ), \esc_url( \admin_url( 'admin.php?page=advan_wp_panel#security-and-api' ) ) ), $details ); } return static::pass( __( 'XML-RPC appears to be blocked or not functioning, which is good for security.', '0-day-analytics' ), $details ); } } }