wpmudev = wd_di()->get( WPMUDEV::class );
}
/**
* This function processes the request to disable XML-RPC.
*
* @return bool Returns true if the function successfully executes.
*/
public function process(): bool {
// Update the site option for the current instance of the class to "ON".
update_site_option( $this->slug, 'ON' );
// Return true to indicate that the function executed successfully.
return true;
}
/**
* Reverts the XML-RPC toggle to the "off" state.
*
* @return bool Returns true if the function successfully executes.
*/
public function revert(): bool {
// Set the XML-RPC toggle to "OFF".
update_site_option( $this->slug, 'OFF' );
// Return true to indicate that the function executed successfully.
return true;
}
/**
* Shield up. It runs on every page load when xml-rpc is disabled.
*
* @return void
*/
public function shield_up(): void {
// Check if this tweak has been enabled.
$this->resolved = $this->check();
// if this tweak is ON, block XML-RPC.
if ( $this->resolved ) {
$this->add_hooks();
}
}
/**
* Queue hooks when this class init.
*
* @return void
*/
public function add_hooks(): void {
// Disable XML-RPC methods that require authentication.
add_filter( 'xmlrpc_enabled', '__return_false' );
// Class used for handling XML-RPC requests.
add_filter( 'wp_xmlrpc_server_class', array( $this, 'send_forbidden_response' ) );
// Methods exposed by the XML-RPC server.
add_filter( 'xmlrpc_methods', '__return_empty_array' );
}
/**
* Check whether the issue has been resolved or not.
*
* @return bool
*/
public function check(): bool {
return $this->is_tweak_enabled_in_site();
}
/**
* Re-check the XML-RPC status.
*
* @return bool
*/
public function recheck(): bool {
// Check if XML-RPC is disabled on Defender (plugin) side.
$plugin_xmlrpc_status = $this->is_tweak_enabled_in_site();
// Check if user is using WPMUDEV hosting.
if ( $this->wpmudev->is_wpmu_hosting() ) {
return $this->determine_status( $plugin_xmlrpc_status, $this->is_tweak_enabled_in_server() ) !== 3;
}
// Return the status of XML-RPC.
return $plugin_xmlrpc_status;
}
/**
* Check whether the tweak is enabled or not in the site.
*
* @return bool
*/
public function is_tweak_enabled_in_site(): bool {
return get_site_option( $this->slug ) === 'ON';
}
/**
* Check whether the tweak is enabled or not in the server.
*
* @return bool
*/
public function is_tweak_enabled_in_server(): bool {
// Check if the current site is hosted by WPMU DEV.
if ( ! $this->wpmudev->is_wpmu_hosting() ) {
// If not, return true to indicate that the tweak is enabled by default.
return true;
}
$server_xmlrpc_status = defender_get_hosting_feature_state( 'xmlrpc_block' );
if ( '' === $server_xmlrpc_status ) {
// Something went wrong.
return false;
}
// Return whether the XML-RPC is enabled or disabled based on the XML-RPC status.
return ! $server_xmlrpc_status;
}
/**
* Determines the status of the XML-RPC feature based on plugin and hosting settings.
*
* @param bool $is_plugin_xmlrpc_enabled Indicates if the plugin's XML-RPC is enabled.
* @param bool $is_hosting_xmlrpc_enabled Indicates if the hosting's XML-RPC is enabled.
*
* @return int The status of the XML-RPC feature.
*/
public function determine_status( bool $is_plugin_xmlrpc_enabled, bool $is_hosting_xmlrpc_enabled ): int {
if ( $is_plugin_xmlrpc_enabled && ! $is_hosting_xmlrpc_enabled ) {
return 1; // Case 1: Defender ON, Hosting OFF.
}
if ( ! $is_plugin_xmlrpc_enabled && $is_hosting_xmlrpc_enabled ) {
return 2; // Case 2: Defender OFF, Hosting ON.
}
if ( ! $is_plugin_xmlrpc_enabled && ! $is_hosting_xmlrpc_enabled ) {
return 3; // Case 3: Defender OFF, Hosting OFF.
}
// If ON both sides then turn it OFF on Defender side.
$this->revert();
return 2; // Case 2: Defender OFF, Hosting ON.
}
/**
* Send a 403 Forbidden response and terminate the script.
*
* @return void
*/
public function send_forbidden_response(): void {
http_response_code( 403 );
exit( esc_html__( 'Forbidden', 'defender-security' ) );
}
/**
* Retrieve the tweak's label.
*
* @return string
*/
public function get_label(): string {
return esc_html__( 'Disable XML-RPC', 'defender-security' );
}
/**
* Get the error reason.
*
* @return string
*/
public function get_error_reason(): string {
return esc_html__( 'XML-RPC is currently enabled.', 'defender-security' );
}
/**
* Return a summary data of this tweak.
*
* @return array
*/
public function to_array(): array {
// The message to display if the XML-RPC feature is disabled.
$enabled = esc_html__( 'XML-RPC is disabled, great job!', 'defender-security' );
// Determine if the XML-RPC feature is enabled on the server side.
$in_server = $this->is_tweak_enabled_in_server();
// Determine if the XML-RPC feature is enabled on the plugin side.
$in_site = $this->is_tweak_enabled_in_site();
// If the site is not hosted on WPMU DEV's hosting, return the summary data.
if ( $this->wpmudev->is_wpmu_hosting() && $this->wpmudev->is_dash_activated() && $this->wpmudev->get_site_id() ) {
// If the site is hosted on WPMU DEV's hosting, construct the URL to the hosting settings page.
$url = 'https://wpmudev.com/hub2/site/' . $this->wpmudev->get_site_id() . '/hosting/tools#block-xml-rpc';
// If the XML-RPC feature is enabled on the server side, construct the message to display.
if ( $in_server ) {
if ( $this->wpmudev->is_whitelabel_enabled() ) {
$enabled = esc_html__( 'You can manage the XML-RPC settings in the Hosting Settings.', 'defender-security' );
} else {
$enabled = sprintf(
/* translators: %1$s: link to admin page, %2$s: closing link tag. */
esc_html__( 'You can manage XML-RPC settings from Hosting Settings by going to %1$sthis link%2$s.', 'defender-security' ),
'',
''
);
}
} elseif ( $this->wpmudev->is_whitelabel_enabled() ) {
$enabled = esc_html__( 'XML-RPC is currently disabled on plugin side.', 'defender-security' );
} else {
// If the XML-RPC feature is disabled on the plugin side but enabled on the server side, construct the message to display.
$enabled = sprintf(
/* translators: %1$s: link to admin page, %2$s: closing link tag. */
esc_html__( 'XML-RPC is currently disabled on plugin side, we suggest disabling it from server side by clicking on %1$sthis link%2$s.', 'defender-security' ),
'',
''
);
}
// Return the summary data.
return array(
'slug' => $this->slug,
'title' => $this->get_label(),
'errorReason' => $this->get_error_reason(),
'successReason' => $enabled,
'misc' => array(
'show_revert_button' => $this->determine_status( $in_site, $in_server ) !== 2,
),
'bulk_description' => esc_html__( 'In the past, there were security concerns with XML-RPC so we recommend making sure this feature is fully disabled if you don’t need it active. We will disable XML-RPC for you.', 'defender-security' ),
'bulk_title' => 'XML-RPC',
);
}
return array(
'slug' => $this->slug,
'title' => $this->get_label(),
'errorReason' => $this->get_error_reason(),
'successReason' => $enabled,
'misc' => array(
'show_revert_button' => $in_site,
),
'bulk_description' => esc_html__( 'In the past, there were security concerns with XML-RPC so we recommend making sure this feature is fully disabled if you don’t need it active. We will disable XML-RPC for you.', 'defender-security' ),
'bulk_title' => 'XML-RPC',
);
}
}