PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.8.1
Defender Security – Malware Scanner, Login Security & Firewall v5.8.1
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / component / security-tweaks / class-disable-xml-rpc.php

class-disable-xml-rpc.php in Defender Security – Malware Scanner, Login Security & Firewall 5.8.1, at src/component/security-tweaks/class-disable-xml-rpc.php

283 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Responsible for disabling XML-RPC functionality in WordPress.
4 *
5 * @package WP_Defender\Component\Security_Tweaks
6 */
7
8 namespace WP_Defender\Component\Security_Tweaks;
9
10 use WP_Defender\Traits\IO;
11 use WP_Defender\Behavior\WPMUDEV;
12
13 /**
14 * XML-RPC can be a security risk if not properly managed, and this class provides methods to disable it and ensure it
15 * remains disabled.
16 */
17 class Disable_XML_RPC extends Abstract_Security_Tweaks {
18
19 use IO;
20
21 /**
22 * Unique identifier for the tweak.
23 *
24 * @var string $slug
25 */
26 public string $slug = 'disable-xml-rpc';
27
28 /**
29 * Indicates whether the issue has been resolved.
30 *
31 * @var bool
32 */
33 public bool $resolved = false;
34
35 /**
36 * This class contains everything relate to WPMUDEV.
37 *
38 * @var WPMUDEV|null
39 */
40 private ?WPMUDEV $wpmudev;
41
42 /**
43 * Class constructor to initialize the Disable_XML_RPC component.
44 *
45 * @return void
46 */
47 public function __construct() {
48 $this->wpmudev = wd_di()->get( WPMUDEV::class );
49 }
50
51 /**
52 * This function processes the request to disable XML-RPC.
53 *
54 * @return bool Returns true if the function successfully executes.
55 */
56 public function process(): bool {
57 // Update the site option for the current instance of the class to "ON".
58 update_site_option( $this->slug, 'ON' );
59
60 // Return true to indicate that the function executed successfully.
61 return true;
62 }
63
64 /**
65 * Reverts the XML-RPC toggle to the "off" state.
66 *
67 * @return bool Returns true if the function successfully executes.
68 */
69 public function revert(): bool {
70 // Set the XML-RPC toggle to "OFF".
71 update_site_option( $this->slug, 'OFF' );
72
73 // Return true to indicate that the function executed successfully.
74 return true;
75 }
76
77 /**
78 * Shield up. It runs on every page load when xml-rpc is disabled.
79 *
80 * @return void
81 */
82 public function shield_up(): void {
83 // Check if this tweak has been enabled.
84 $this->resolved = $this->check();
85 // if this tweak is ON, block XML-RPC.
86 if ( $this->resolved ) {
87 $this->add_hooks();
88 }
89 }
90
91 /**
92 * Queue hooks when this class init.
93 *
94 * @return void
95 */
96 public function add_hooks(): void {
97 // Disable XML-RPC methods that require authentication.
98 add_filter( 'xmlrpc_enabled', '__return_false' );
99 // Class used for handling XML-RPC requests.
100 add_filter( 'wp_xmlrpc_server_class', array( $this, 'send_forbidden_response' ) );
101 // Methods exposed by the XML-RPC server.
102 add_filter( 'xmlrpc_methods', '__return_empty_array' );
103 }
104
105 /**
106 * Check whether the issue has been resolved or not.
107 *
108 * @return bool
109 */
110 public function check(): bool {
111 return $this->is_tweak_enabled_in_site();
112 }
113
114 /**
115 * Re-check the XML-RPC status.
116 *
117 * @return bool
118 */
119 public function recheck(): bool {
120 // Check if XML-RPC is disabled on Defender (plugin) side.
121 $plugin_xmlrpc_status = $this->is_tweak_enabled_in_site();
122 // Check if user is using WPMUDEV hosting.
123 if ( $this->wpmudev->is_wpmu_hosting() ) {
124 return $this->determine_status( $plugin_xmlrpc_status, $this->is_tweak_enabled_in_server() ) !== 3;
125 }
126 // Return the status of XML-RPC.
127 return $plugin_xmlrpc_status;
128 }
129
130 /**
131 * Check whether the tweak is enabled or not in the site.
132 *
133 * @return bool
134 */
135 public function is_tweak_enabled_in_site(): bool {
136 return get_site_option( $this->slug ) === 'ON';
137 }
138
139 /**
140 * Check whether the tweak is enabled or not in the server.
141 *
142 * @return bool
143 */
144 public function is_tweak_enabled_in_server(): bool {
145 // Check if the current site is hosted by WPMU DEV.
146 if ( ! $this->wpmudev->is_wpmu_hosting() ) {
147 // If not, return true to indicate that the tweak is enabled by default.
148 return true;
149 }
150
151 $server_xmlrpc_status = defender_get_hosting_feature_state( 'xmlrpc_block' );
152 if ( '' === $server_xmlrpc_status ) {
153 // Something went wrong.
154 return false;
155 }
156 // Return whether the XML-RPC is enabled or disabled based on the XML-RPC status.
157 return ! $server_xmlrpc_status;
158 }
159
160 /**
161 * Determines the status of the XML-RPC feature based on plugin and hosting settings.
162 *
163 * @param bool $is_plugin_xmlrpc_enabled Indicates if the plugin's XML-RPC is enabled.
164 * @param bool $is_hosting_xmlrpc_enabled Indicates if the hosting's XML-RPC is enabled.
165 *
166 * @return int The status of the XML-RPC feature.
167 */
168 public function determine_status( bool $is_plugin_xmlrpc_enabled, bool $is_hosting_xmlrpc_enabled ): int {
169 if ( $is_plugin_xmlrpc_enabled && ! $is_hosting_xmlrpc_enabled ) {
170 return 1; // Case 1: Defender ON, Hosting OFF.
171 }
172
173 if ( ! $is_plugin_xmlrpc_enabled && $is_hosting_xmlrpc_enabled ) {
174 return 2; // Case 2: Defender OFF, Hosting ON.
175 }
176
177 if ( ! $is_plugin_xmlrpc_enabled && ! $is_hosting_xmlrpc_enabled ) {
178 return 3; // Case 3: Defender OFF, Hosting OFF.
179 }
180
181 // If ON both sides then turn it OFF on Defender side.
182 $this->revert();
183 return 2; // Case 2: Defender OFF, Hosting ON.
184 }
185
186 /**
187 * Send a 403 Forbidden response and terminate the script.
188 *
189 * @return void
190 */
191 public function send_forbidden_response(): void {
192 http_response_code( 403 );
193 exit( esc_html__( 'Forbidden', 'defender-security' ) );
194 }
195
196 /**
197 * Retrieve the tweak's label.
198 *
199 * @return string
200 */
201 public function get_label(): string {
202 return esc_html__( 'Disable XML-RPC', 'defender-security' );
203 }
204
205 /**
206 * Get the error reason.
207 *
208 * @return string
209 */
210 public function get_error_reason(): string {
211 return esc_html__( 'XML-RPC is currently enabled.', 'defender-security' );
212 }
213
214 /**
215 * Return a summary data of this tweak.
216 *
217 * @return array
218 */
219 public function to_array(): array {
220 // The message to display if the XML-RPC feature is disabled.
221 $enabled = esc_html__( 'XML-RPC is disabled, great job!', 'defender-security' );
222 // Determine if the XML-RPC feature is enabled on the server side.
223 $in_server = $this->is_tweak_enabled_in_server();
224 // Determine if the XML-RPC feature is enabled on the plugin side.
225 $in_site = $this->is_tweak_enabled_in_site();
226
227 // If the site is not hosted on WPMU DEV's hosting, return the summary data.
228 if ( $this->wpmudev->is_wpmu_hosting() && $this->wpmudev->is_dash_activated() && $this->wpmudev->get_site_id() ) {
229 // If the site is hosted on WPMU DEV's hosting, construct the URL to the hosting settings page.
230 $url = 'https://wpmudev.com/hub2/site/' . $this->wpmudev->get_site_id() . '/hosting/tools#block-xml-rpc';
231
232 // If the XML-RPC feature is enabled on the server side, construct the message to display.
233 if ( $in_server ) {
234 if ( $this->wpmudev->is_whitelabel_enabled() ) {
235 $enabled = esc_html__( 'You can manage the XML-RPC settings in the Hosting Settings.', 'defender-security' );
236 } else {
237 $enabled = sprintf(
238 /* translators: %1$s: link to admin page, %2$s: closing link tag. */
239 esc_html__( 'You can manage XML-RPC settings from Hosting Settings by going to %1$sthis link%2$s.', 'defender-security' ),
240 '<a target="_blank" href="' . $url . '">',
241 '</a>'
242 );
243 }
244 } elseif ( $this->wpmudev->is_whitelabel_enabled() ) {
245 $enabled = esc_html__( 'XML-RPC is currently disabled on plugin side.', 'defender-security' );
246 } else {
247 // If the XML-RPC feature is disabled on the plugin side but enabled on the server side, construct the message to display.
248 $enabled = sprintf(
249 /* translators: %1$s: link to admin page, %2$s: closing link tag. */
250 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' ),
251 '<a target="_blank" href="' . $url . '">',
252 '</a>'
253 );
254 }
255
256 // Return the summary data.
257 return array(
258 'slug' => $this->slug,
259 'title' => $this->get_label(),
260 'errorReason' => $this->get_error_reason(),
261 'successReason' => $enabled,
262 'misc' => array(
263 'show_revert_button' => $this->determine_status( $in_site, $in_server ) !== 2,
264 ),
265 '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' ),
266 'bulk_title' => 'XML-RPC',
267 );
268 }
269
270 return array(
271 'slug' => $this->slug,
272 'title' => $this->get_label(),
273 'errorReason' => $this->get_error_reason(),
274 'successReason' => $enabled,
275 'misc' => array(
276 'show_revert_button' => $in_site,
277 ),
278 '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' ),
279 'bulk_title' => 'XML-RPC',
280 );
281 }
282 }
283