Changeset 3376009
- Timestamp:
- 10/09/2025 11:43:06 PM (4 months ago)
- Location:
- stop-xml-rpc-attacks/trunk
- Files:
-
- 2 added
- 2 edited
-
languages (added)
-
languages/stop-xml-rpc-attacks.pot (added)
-
readme.txt (modified) (1 diff)
-
stop-xml-rpc-attacks.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
stop-xml-rpc-attacks/trunk/readme.txt
r3275121 r3376009 1 === stop XML-RPC Attacks ===1 === Stop XML-RPC Attacks === 2 2 Contributors: pcescato 3 Tags: xml-rpc, pingback, ddos, multicall4 Requires at least: 5.03 Tags: security, xmlrpc, brute force, ddos, jetpack 4 Requires at least: 6.0 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 1.0.17 Stable tag: 2.0.0 8 8 License: GPLv3 9 License URI: https://www.gnu.org/licenses/gpl .html9 License URI: https://www.gnu.org/licenses/gpl-3.0.html 10 10 11 Secure your site's XML-RPC by removing some methods, while you can still use XML-RPC.11 Blocks dangerous XML-RPC methods while preserving Jetpack, WooCommerce, and mobile apps compatibility. 12 12 13 13 == Description == 14 14 15 S ecure your site's XML-RPC by removing some methods, instead of disabling totally XML-RPC, which is needed by some plugins (eg. Jetpack) and some mobile apps.15 Stop XML-RPC Attacks protects your WordPress site from XML-RPC brute force attacks, DDoS attempts, and reconnaissance probes while maintaining compatibility with essential services like Jetpack and WooCommerce. 16 16 17 = Features = 17 **Features:** 18 18 19 Removes the following methods from XML-RPC interface. 19 * Three security modes: Full Disable, Guest Disable, or Selective Blocking 20 * Blocks dangerous methods: system.multicall, pingback.ping, and more 21 * Compatible with Jetpack and WooCommerce 22 * Optional user enumeration blocking 23 * Attack logging for monitoring 24 * Zero configuration required - works out of the box 25 * Clean, intuitive admin interface 20 26 21 * system.multicall22 * system.listMethods23 * system.getCapabilities24 * pingback.extensions.getPingbacks25 * pingback.ping26 * X-Pingback from HTTP headers27 28 This is not perfect, but it will help prerventing attacks29 30 = Requirements =31 32 * WordPress 5.0 or higher.33 34 27 == Installation == 35 28 36 * Extract the zip file and just drop the contents in the <code>wp-content/plugins/</code> directory of your WordPress installation or install it directly from your dashboard and then activate the plugin from Plugins page. 37 * There's not options page, simply install and activate. 29 1. Upload the plugin files to `/wp-content/plugins/stop-xmlrpc-attacks/` 30 2. Activate the plugin through the 'Plugins' menu in WordPress 31 3. Go to Settings > XML-RPC Security to configure (optional) 38 32 39 33 == Frequently Asked Questions == 40 34 41 = Is there something to do after install? =35 = Will this break Jetpack? = 42 36 43 Yes, just activate it! 37 No! The default "Selective Blocking" mode is fully compatible with Jetpack and WooCommerce. 44 38 45 = I already have a security plugin, do I need this plugin too? =39 = What's the difference between the security modes? = 46 40 47 It depends on your security plugin. Some secure XML-RPC, some just allow you to enable or disable it, some can stop attacks as *Stop XML-RPC Attacks* does. So you may have to read your security plugin FAQ / doc. 41 * **Full Disable**: Maximum security, disables XML-RPC completely 42 * **Guest Disable**: Balanced approach, only allows XML-RPC for logged-in users 43 * **Selective Blocking**: Best compatibility, only blocks dangerous methods 48 44 49 45 = How do I enable logging? = 46 47 Go to Settings > XML-RPC Security and check "Enable Attack Logging". Logs will be written to your debug.log file when WP_DEBUG is enabled. 48 50 49 == Changelog == 51 50 52 = 1.0 = 51 = 2.0.0 = 52 * Added admin interface with visual settings 53 * Three security modes to choose from 54 * Optional attack logging 55 * Improved code quality and security 56 * Full internationalization support 53 57 58 = 1.0.1 = 54 59 * Initial release 60 * Basic blocking of dangerous methods 61 62 == Upgrade Notice == 63 64 = 2.0.0 = 65 Major update with admin interface. -
stop-xml-rpc-attacks/trunk/stop-xml-rpc-attacks.php
r2812646 r3376009 1 1 <?php 2 3 2 /* 4 3 Plugin Name: Stop XML-RPC Attacks 5 Description: Secure your site's XML-RPC by removing some methods, while you can still use XML-RPC.4 Description: Blocks dangerous XML-RPC methods while preserving Jetpack, WooCommerce, and mobile apps. Choose between full disable, guest-only disable, or selective blocking. 6 5 Author: Pascal CESCATO 7 Version: 1.0.18 Author URI: https:// tsw.ovh6 Version: 2.0.0 7 Author URI: https://zone-test.ovh 9 8 License: GPLv3 10 */ 11 12 /* 13 This program is free software: you can redistribute it and/or modify 14 it under the terms of the GNU General Public License version 2 as published by 15 the Free Software Foundation. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program. If not, see <https://www.gnu.org/licenses/gpl.html>. 24 */ 25 26 add_filter('xmlrpc_methods', function ($methods) { 27 unset($methods['system.multicall']); 28 unset($methods['system.listMethods']); 29 unset($methods['system.getCapabilities']); 30 unset($methods['pingback.extensions.getPingbacks']); 31 unset($methods['pingback.ping']); 32 return $methods; 33 }); 34 35 add_action('wp', function () { 36 header_remove('X-Pingback'); 37 }, 9999); 9 Text Domain: stop-xml-rpc-attacks 10 Domain Path: /languages 11 */ 12 13 if (!defined('ABSPATH')) exit; 14 15 define('SXRA_VERSION', '2.0.0'); 16 17 class Stop_XMLRPC_Attacks { 18 private static $instance = null; 19 private $option_name = 'sxra_settings'; 20 private $default_blocked_methods = [ 21 'system.multicall', 22 'system.listMethods', 23 'system.getCapabilities', 24 'pingback.ping', 25 'pingback.extensions.getPingbacks', 26 ]; 27 28 private $enumeration_methods = [ 29 'wp.getUsersBlogs', 30 'wp.getCategories', 31 'wp.getTags', 32 ]; 33 34 public static function init() { 35 if (self::$instance === null) { 36 self::$instance = new self(); 37 } 38 return self::$instance; 39 } 40 41 private function __construct() { 42 // Admin interface 43 if (is_admin()) { 44 add_action('admin_menu', [$this, 'add_admin_menu']); 45 add_action('admin_init', [$this, 'register_settings']); 46 add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_styles']); 47 } 48 49 // Get settings 50 $settings = $this->get_settings(); 51 $mode = $settings['security_mode']; 52 53 // Apply security mode 54 switch ($mode) { 55 case 'full_disable': 56 add_filter('xmlrpc_enabled', '__return_false'); 57 break; 58 59 case 'guest_disable': 60 add_filter('xmlrpc_enabled', [$this, 'disable_for_guests']); 61 add_filter('xmlrpc_methods', [$this, 'block_dangerous_methods']); 62 break; 63 64 case 'selective': 65 default: 66 add_filter('xmlrpc_methods', [$this, 'block_dangerous_methods']); 67 break; 68 } 69 70 // Always remove headers and links 71 add_action('init', [$this, 'remove_headers_and_links'], 1); 72 add_action('send_headers', [$this, 'remove_pingback_header']); 73 74 // Optional logging 75 if ($settings['enable_logging']) { 76 add_filter('xmlrpc_call', [$this, 'log_blocked_attempts']); 77 } 78 } 79 80 private function get_settings() { 81 $defaults = [ 82 'security_mode' => 'selective', 83 'block_enumeration' => false, 84 'enable_logging' => false, 85 ]; 86 return wp_parse_args(get_option($this->option_name, []), $defaults); 87 } 88 89 public function add_admin_menu() { 90 add_options_page( 91 __('Stop XML-RPC Attacks', 'stop-xml-rpc-attacks'), 92 __('XML-RPC Security', 'stop-xml-rpc-attacks'), 93 'manage_options', 94 'stop-xmlrpc-attacks', 95 [$this, 'render_admin_page'] 96 ); 97 } 98 99 public function register_settings() { 100 register_setting($this->option_name, $this->option_name, [$this, 'sanitize_settings']); 101 } 102 103 public function sanitize_settings($input) { 104 $sanitized = []; 105 $sanitized['security_mode'] = in_array($input['security_mode'], ['full_disable', 'guest_disable', 'selective']) 106 ? $input['security_mode'] 107 : 'selective'; 108 $sanitized['block_enumeration'] = isset($input['block_enumeration']); 109 $sanitized['enable_logging'] = isset($input['enable_logging']); 110 return $sanitized; 111 } 112 113 public function enqueue_admin_styles($hook) { 114 if ($hook !== 'settings_page_stop-xmlrpc-attacks') { 115 return; 116 } 117 118 wp_add_inline_style('wp-admin', ' 119 .sxra-card { 120 background: #fff; 121 border: 1px solid #ccd0d4; 122 border-radius: 4px; 123 padding: 20px; 124 margin-bottom: 20px; 125 box-shadow: 0 1px 1px rgba(0,0,0,.04); 126 } 127 .sxra-card h3 { 128 margin-top: 0; 129 border-bottom: 1px solid #eee; 130 padding-bottom: 10px; 131 } 132 .sxra-option { 133 margin: 15px 0; 134 padding: 15px; 135 background: #f9f9f9; 136 border-left: 4px solid #2271b1; 137 border-radius: 3px; 138 } 139 .sxra-option label { 140 font-weight: 600; 141 display: block; 142 margin-bottom: 5px; 143 } 144 .sxra-option p { 145 margin: 5px 0 0 0; 146 color: #646970; 147 font-size: 13px; 148 } 149 .sxra-stats { 150 display: grid; 151 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); 152 gap: 15px; 153 margin-top: 20px; 154 } 155 .sxra-stat-box { 156 background: #f0f6fc; 157 border-left: 4px solid #2271b1; 158 padding: 15px; 159 border-radius: 3px; 160 } 161 .sxra-stat-box strong { 162 display: block; 163 font-size: 24px; 164 color: #2271b1; 165 margin-bottom: 5px; 166 } 167 .sxra-warning { 168 background: #fcf3cd; 169 border-left-color: #dba617; 170 } 171 .sxra-success { 172 background: #d5f4e6; 173 border-left-color: #00a32a; 174 } 175 '); 176 } 177 178 private function get_security_mode_label($mode) { 179 $labels = [ 180 'full_disable' => __('Full Disable', 'stop-xml-rpc-attacks'), 181 'guest_disable' => __('Guest Disable', 'stop-xml-rpc-attacks'), 182 'selective' => __('Selective Blocking', 'stop-xml-rpc-attacks'), 183 ]; 184 return isset($labels[$mode]) ? $labels[$mode] : $labels['selective']; 185 } 186 187 public function render_admin_page() { 188 if (!current_user_can('manage_options')) { 189 return; 190 } 191 192 $settings = $this->get_settings(); 193 $blocked_count = count($this->default_blocked_methods); 194 if ($settings['block_enumeration']) { 195 $blocked_count += count($this->enumeration_methods); 196 } 197 198 ?> 199 <div class="wrap"> 200 <h1><?php echo esc_html(get_admin_page_title()); ?></h1> 201 <p><?php esc_html_e('Protect your WordPress site from XML-RPC attacks while maintaining compatibility with essential services.', 'stop-xml-rpc-attacks'); ?></p> 202 203 <div class="sxra-card"> 204 <h3><?php esc_html_e('Current Status', 'stop-xml-rpc-attacks'); ?></h3> 205 <div class="sxra-stats"> 206 <div class="sxra-stat-box sxra-success"> 207 <strong><?php echo esc_html($blocked_count); ?></strong> 208 <span><?php esc_html_e('Methods Blocked', 'stop-xml-rpc-attacks'); ?></span> 209 </div> 210 <div class="sxra-stat-box"> 211 <strong><?php echo esc_html($this->get_security_mode_label($settings['security_mode'])); ?></strong> 212 <span><?php esc_html_e('Security Mode', 'stop-xml-rpc-attacks'); ?></span> 213 </div> 214 <div class="sxra-stat-box <?php echo $settings['enable_logging'] ? 'sxra-success' : ''; ?>"> 215 <strong><?php echo $settings['enable_logging'] ? esc_html__('ON', 'stop-xml-rpc-attacks') : esc_html__('OFF', 'stop-xml-rpc-attacks'); ?></strong> 216 <span><?php esc_html_e('Attack Logging', 'stop-xml-rpc-attacks'); ?></span> 217 </div> 218 </div> 219 </div> 220 221 <form method="post" action="options.php"> 222 <?php settings_fields($this->option_name); ?> 223 224 <div class="sxra-card"> 225 <h3><?php esc_html_e('Security Mode', 'stop-xml-rpc-attacks'); ?></h3> 226 227 <div class="sxra-option <?php echo $settings['security_mode'] === 'full_disable' ? 'sxra-success' : ''; ?>"> 228 <label> 229 <input type="radio" name="<?php echo esc_attr($this->option_name); ?>[security_mode]" 230 value="full_disable" <?php checked($settings['security_mode'], 'full_disable'); ?>> 231 <strong><?php esc_html_e('Full Disable', 'stop-xml-rpc-attacks'); ?></strong> <?php esc_html_e('(Maximum Security)', 'stop-xml-rpc-attacks'); ?> 232 </label> 233 <p><?php esc_html_e('Completely disables XML-RPC. Use this if you don\'t need Jetpack, WooCommerce mobile apps, or WordPress mobile app.', 'stop-xml-rpc-attacks'); ?></p> 234 </div> 235 236 <div class="sxra-option <?php echo $settings['security_mode'] === 'guest_disable' ? 'sxra-warning' : ''; ?>"> 237 <label> 238 <input type="radio" name="<?php echo esc_attr($this->option_name); ?>[security_mode]" 239 value="guest_disable" <?php checked($settings['security_mode'], 'guest_disable'); ?>> 240 <strong><?php esc_html_e('Guest Disable', 'stop-xml-rpc-attacks'); ?></strong> <?php esc_html_e('(Balanced)', 'stop-xml-rpc-attacks'); ?> 241 </label> 242 <p><?php esc_html_e('Disables XML-RPC for non-logged-in users, but allows it for administrators. Blocks dangerous methods for logged-in users.', 'stop-xml-rpc-attacks'); ?></p> 243 </div> 244 245 <div class="sxra-option <?php echo $settings['security_mode'] === 'selective' ? 'sxra-warning' : ''; ?>"> 246 <label> 247 <input type="radio" name="<?php echo esc_attr($this->option_name); ?>[security_mode]" 248 value="selective" <?php checked($settings['security_mode'], 'selective'); ?>> 249 <strong><?php esc_html_e('Selective Blocking', 'stop-xml-rpc-attacks'); ?></strong> <?php esc_html_e('(Best Compatibility)', 'stop-xml-rpc-attacks'); ?> 250 </label> 251 <p><?php esc_html_e('Only blocks known dangerous methods. Use this if you need full Jetpack or WooCommerce functionality.', 'stop-xml-rpc-attacks'); ?></p> 252 </div> 253 </div> 254 255 <div class="sxra-card"> 256 <h3><?php esc_html_e('Advanced Options', 'stop-xml-rpc-attacks'); ?></h3> 257 258 <div class="sxra-option"> 259 <label> 260 <input type="checkbox" name="<?php echo esc_attr($this->option_name); ?>[block_enumeration]" 261 value="1" <?php checked($settings['block_enumeration']); ?>> 262 <strong><?php esc_html_e('Block User Enumeration Methods', 'stop-xml-rpc-attacks'); ?></strong> 263 </label> 264 <p><?php esc_html_e('Blocks methods that can reveal usernames. Warning: This will break WordPress mobile apps and some third-party tools.', 'stop-xml-rpc-attacks'); ?></p> 265 </div> 266 267 <div class="sxra-option"> 268 <label> 269 <input type="checkbox" name="<?php echo esc_attr($this->option_name); ?>[enable_logging]" 270 value="1" <?php checked($settings['enable_logging']); ?>> 271 <strong><?php esc_html_e('Enable Attack Logging', 'stop-xml-rpc-attacks'); ?></strong> 272 </label> 273 <p><?php esc_html_e('Logs blocked XML-RPC attempts to your debug.log file. Useful for monitoring attacks.', 'stop-xml-rpc-attacks'); ?></p> 274 </div> 275 </div> 276 277 <div class="sxra-card"> 278 <h3><?php esc_html_e('Blocked Methods', 'stop-xml-rpc-attacks'); ?></h3> 279 <p><strong> 280 <?php 281 /* translators: %d: number of blocked methods */ 282 echo esc_html(sprintf(__('Always blocked (%d):', 'stop-xml-rpc-attacks'), count($this->default_blocked_methods))); 283 ?> 284 </strong></p> 285 <ul> 286 <?php foreach ($this->default_blocked_methods as $method): ?> 287 <li><code><?php echo esc_html($method); ?></code></li> 288 <?php endforeach; ?> 289 </ul> 290 291 <?php if ($settings['block_enumeration']): ?> 292 <p><strong> 293 <?php 294 /* translators: %d: number of additionally blocked methods */ 295 echo esc_html(sprintf(__('Additionally blocked (%d):', 'stop-xml-rpc-attacks'), count($this->enumeration_methods))); 296 ?> 297 </strong></p> 298 <ul> 299 <?php foreach ($this->enumeration_methods as $method): ?> 300 <li><code><?php echo esc_html($method); ?></code></li> 301 <?php endforeach; ?> 302 </ul> 303 <?php endif; ?> 304 </div> 305 306 <?php submit_button(__('Save Security Settings', 'stop-xml-rpc-attacks'), 'primary large'); ?> 307 </form> 308 309 <div class="sxra-card"> 310 <h3><?php esc_html_e('About This Plugin', 'stop-xml-rpc-attacks'); ?></h3> 311 <p><strong><?php esc_html_e('Version:', 'stop-xml-rpc-attacks'); ?></strong> <?php echo esc_html(SXRA_VERSION); ?></p> 312 <p><strong><?php esc_html_e('Author:', 'stop-xml-rpc-attacks'); ?></strong> <a href="https://tsw.ovh" target="_blank" rel="noopener noreferrer">Pascal CESCATO</a></p> 313 <p><?php esc_html_e('This plugin protects your WordPress site from XML-RPC brute force attacks, DDoS attempts, and reconnaissance probes while maintaining compatibility with essential services like Jetpack and WooCommerce.', 'stop-xml-rpc-attacks'); ?></p> 314 </div> 315 </div> 316 <?php 317 } 318 319 public function disable_for_guests($enabled) { 320 return is_user_logged_in() ? $enabled : false; 321 } 322 323 public function block_dangerous_methods($methods) { 324 if (!defined('XMLRPC_REQUEST') || !XMLRPC_REQUEST) { 325 return $methods; 326 } 327 328 $settings = $this->get_settings(); 329 $blocked = $this->default_blocked_methods; 330 331 if ($settings['block_enumeration']) { 332 $blocked = array_merge($blocked, $this->enumeration_methods); 333 } 334 335 $blocked = apply_filters('sxra_blocked_xmlrpc_methods', $blocked); 336 337 foreach ($blocked as $method) { 338 unset($methods[$method]); 339 } 340 341 return $methods; 342 } 343 344 public function log_blocked_attempts($method) { 345 $settings = $this->get_settings(); 346 $blocked = $this->default_blocked_methods; 347 348 if ($settings['block_enumeration']) { 349 $blocked = array_merge($blocked, $this->enumeration_methods); 350 } 351 352 if (in_array($method, $blocked)) { 353 $ip = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : ('CLI' === php_sapi_name() ? 'CLI' : 'unknown'); 354 355 // Only log in development/debug mode 356 if (defined('WP_DEBUG') && WP_DEBUG) { 357 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only runs when WP_DEBUG is enabled 358 error_log(sprintf( 359 '[Stop XML-RPC v%s] Blocked dangerous method "%s" from IP: %s', 360 SXRA_VERSION, 361 $method, 362 $ip 363 )); 364 } 365 } 366 return $method; 367 } 368 369 public function remove_headers_and_links() { 370 remove_action('wp_head', 'rsd_link'); 371 remove_action('wp_head', 'wlwmanifest_link'); 372 373 add_filter('wp_headers', function($headers) { 374 unset($headers['X-Pingback']); 375 return $headers; 376 }); 377 } 378 379 public function remove_pingback_header() { 380 if (function_exists('header_remove')) { 381 header_remove('X-Pingback'); 382 } 383 } 384 } 385 386 // Initialize plugin 387 Stop_XMLRPC_Attacks::init();
Note: See TracChangeset
for help on using the changeset viewer.