Changeset 3481949
- Timestamp:
- 03/13/2026 11:59:03 AM (2 weeks ago)
- Location:
- advanced-ip-blocker/trunk
- Files:
-
- 15 edited
-
advanced-ip-blocker.php (modified) (2 diffs)
-
css/advaipbl-styles.css (modified) (1 diff)
-
includes/class-advaipbl-action-handler.php (modified) (5 diffs)
-
includes/class-advaipbl-admin-pages.php (modified) (1 diff)
-
includes/class-advaipbl-ajax-handler.php (modified) (5 diffs)
-
includes/class-advaipbl-community-manager.php (modified) (3 diffs)
-
includes/class-advaipbl-main.php (modified) (20 diffs)
-
includes/class-advaipbl-settings-manager.php (modified) (9 diffs)
-
includes/class-advaipbl-site-scanner.php (modified) (2 diffs)
-
js/admin-settings.js (modified) (1 diff)
-
languages/advanced-ip-blocker-es_ES.mo (modified) (previous)
-
languages/advanced-ip-blocker-es_ES.po (modified) (2 diffs)
-
languages/advanced-ip-blocker.pot (modified) (2 diffs)
-
readme.txt (modified) (4 diffs)
-
uninstall.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
advanced-ip-blocker/trunk/advanced-ip-blocker.php
r3476940 r3481949 4 4 Plugin URI: https://advaipbl.com/ 5 5 Description: Your complete WordPress security firewall. Blocks IPs, bots & countries. Includes an intelligent WAF, Threat Scoring, and Two-Factor Authentication. 6 Version: 8. 8.96 Version: 8.9.0 7 7 Author: IniLerm 8 8 Author URI: https://advaipbl.com/ … … 19 19 } 20 20 21 define( 'ADVAIPBL_VERSION', '8. 8.9' );21 define( 'ADVAIPBL_VERSION', '8.9.0' ); 22 22 define( 'ADVAIPBL_PLUGIN_FILE', __FILE__ ); 23 23 -
advanced-ip-blocker/trunk/css/advaipbl-styles.css
r3476940 r3481949 1 1 /** 2 2 * Advanced IP Blocker - Admin Panel Styles 3 * Version: 8. 8.93 * Version: 8.9.0 4 4 */ 5 5 -
advanced-ip-blocker/trunk/includes/class-advaipbl-action-handler.php
r3476940 r3481949 95 95 96 96 if ($processed_count > 0) { 97 $this->plugin->purge_all_page_caches(); 97 98 /* translators: %d: Number of entries. */ 98 99 $message = sprintf(_n('%d entry has been unblocked.', '%d entries have been unblocked.', $processed_count, 'advanced-ip-blocker'), $processed_count); … … 141 142 case 'unblock_all': 142 143 $this->plugin->unblock_all_ips('Admin Action'); 144 $this->plugin->purge_all_page_caches(); 143 145 $message = __('All blocked IPs have been successfully unblocked.', 'advanced-ip-blocker'); 144 146 break; … … 279 281 } else { 280 282 $this->plugin->block_ip_instantly( $ip_or_range, 'manual', __('Manual Block', 'advanced-ip-blocker'), [], 'admin_action' ); 283 $this->plugin->purge_all_page_caches(); 281 284 /* translators: %s: IP. */ 282 285 $message = sprintf( __( 'Entry %s has been blocked.', 'advanced-ip-blocker' ), $ip_or_range ); … … 285 288 case 'remove_block': 286 289 $this->plugin->desbloquear_ip($ip_or_range); 290 $this->plugin->purge_all_page_caches(); 287 291 /* translators: %s: IP. */ 288 292 $message = sprintf( __( 'IP %s unblocked from all lists.', 'advanced-ip-blocker' ), $ip_or_range ); … … 446 450 $options['enable_community_network'] = '1'; // Compartir (Join) 447 451 $options['enable_community_blocking'] = '1'; // Bloquear (Protect) 452 453 // Generar y registrar el API Token V3 automáticamente en nuevas instalaciones 454 if ( isset( $this->plugin->community_manager ) ) { 455 // Pasamos las opciones actualizadas a la memoria temporal de la clase Main antes de registrar 456 $this->plugin->options = $options; 457 $this->plugin->community_manager->register_site(); 458 // Refrescamos las opciones desde la BD por si register_site las ha modificado directamente. 459 $options = get_option( ADVAIPBL_Main::OPTION_SETTINGS, [] ); 460 } 448 461 } 449 462 -
advanced-ip-blocker/trunk/includes/class-advaipbl-admin-pages.php
r3476940 r3481949 24 24 } 25 25 26 nocache_headers(); // Prevent caching on this admin page 27 26 28 // 1. DEFINIR LA ESTRUCTURA COMPLETA DEL MENÚ 27 29 $menu_structure = [ -
advanced-ip-blocker/trunk/includes/class-advaipbl-ajax-handler.php
r3476940 r3481949 52 52 53 53 if ($success) { 54 $this->plugin->purge_all_page_caches(); 54 55 /* translators: %1$s: IP, %2$s: Username. */ 55 56 $this->plugin->log_event(sprintf(__('Threat score for IP %1$s was manually reset by %2$s.', 'advanced-ip-blocker'), $ip, $this->plugin->get_current_admin_username()), 'info'); … … 291 292 } 292 293 294 // --- Verificación del Token API V3 (Servidor Central AIB) --- 295 if ($provider === 'api_token_v3') { 296 if (empty($api_key)) { 297 wp_send_json_error(['message' => __('API Key is missing.', 'advanced-ip-blocker')]); 298 } 299 300 // Llamada al servidor central para verificar el token real 301 $response = wp_remote_get('https://advaipbl.com/wp-json/aib-api/v3/verify-token', [ 302 'headers' => [ 303 'Authorization' => 'Bearer ' . $api_key, 304 'Accept' => 'application/json' 305 ], 306 'timeout' => 10 307 ]); 308 309 if (is_wp_error($response)) { 310 wp_send_json_error(['message' => __('Connection failed: ', 'advanced-ip-blocker') . $response->get_error_message()]); 311 } 312 313 $status_code = wp_remote_retrieve_response_code($response); 314 $body = wp_remote_retrieve_body($response); 315 $data = json_decode($body, true); 316 317 if ($status_code === 200 && isset($data['status']) && in_array($data['status'], ['active', 'connected'], true)) { 318 wp_send_json_success(['message' => __('API Key is valid and active!', 'advanced-ip-blocker')]); 319 } else { 320 $error_msg = $data['message'] ?? __('Invalid or inactive API Key.', 'advanced-ip-blocker'); 321 wp_send_json_error(['message' => $error_msg]); 322 } 323 return; 324 } 325 293 326 // --- Lógica existente para Geolocalización --- 294 327 $this->plugin->geolocation_manager->set_transient_api_key($provider, $api_key); … … 303 336 } 304 337 } 338 339 /** 340 * AJAX action to get a free API Key from the Central Server automatically. 341 */ 342 public function ajax_get_free_api_key() { 343 check_ajax_referer('advaipbl_verify_api_nonce', 'nonce'); // Usamos este nonce existente 344 345 if (!current_user_can('manage_options')) { 346 wp_send_json_error(['message' => __('Unauthorized', 'advanced-ip-blocker')]); 347 } 348 349 $result = $this->plugin->community_manager->register_site(); 350 351 if (is_wp_error($result)) { 352 wp_send_json_error(['message' => __('Connection to Central Server failed: ', 'advanced-ip-blocker') . $result->get_error_message()]); 353 } 354 355 if (isset($result['api_token'])) { 356 wp_send_json_success([ 357 'message' => __('API Key generated and saved successfully!', 'advanced-ip-blocker'), 358 'api_token_visual' => 'AIB_' . str_repeat('•', 24) . substr($result['api_token'], -4) 359 ]); 360 } else { 361 wp_send_json_error(['message' => __('Failed to generate API Key.', 'advanced-ip-blocker')]); 362 } 363 } 364 305 365 /** 306 366 * Callback de AJAX para gestionar la respuesta al aviso de telemetría. … … 770 830 $skipped_count++; // Duplicate or invalid 771 831 } 832 } 833 834 if ($imported_count > 0) { 835 $this->plugin->purge_all_page_caches(); 772 836 } 773 837 … … 990 1054 } 991 1055 1056 if ($imported_count > 0) { 1057 $this->plugin->purge_all_page_caches(); 1058 } 1059 992 1060 // Si Cloudflare está habilitado, desencadenamos una sincronización asíncrona casi inmediata. 993 1061 // Hacemos esto porque sincronizar miles de IPs de forma síncrona aquí podría agotar el tiempo de espera PHP. -
advanced-ip-blocker/trunk/includes/class-advaipbl-community-manager.php
r3476940 r3481949 6 6 7 7 private $plugin; 8 private $feed_url = 'https://advaipbl.com/wp-content/uploads/advaipbl-feed/blocklist.json'; 8 private $feed_url_v2 = 'https://advaipbl.com/wp-content/uploads/advaipbl-feed/blocklist.json'; 9 private $feed_url_v3 = 'https://advaipbl.com/wp-json/aib-api/v3/community-blocklist'; 9 10 private $last_update_option = 'advaipbl_community_last_update'; 10 11 … … 19 20 */ 20 21 public function update_list() { 21 $response = wp_remote_get($this->feed_url, ['timeout' => 15]); 22 23 if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { 22 $feed_data = false; // Initialize feed_data to store the raw JSON body 23 $api_token = $this->plugin->options['api_token_v3'] ?? ''; 24 25 // VÍA V3 (Prioritaria si hay token) 26 $use_v3 = false; 27 if (!empty($api_token)) { 28 $response = wp_remote_get($this->feed_url_v3, [ 29 'headers' => [ 30 'Authorization' => 'Bearer ' . $api_token, 31 'Accept' => 'application/json' 32 ], 33 'timeout' => 30 34 ]); 35 36 $status_code = wp_remote_retrieve_response_code($response); 37 if (!is_wp_error($response) && $status_code === 200) { 38 $feed_data = wp_remote_retrieve_body($response); 39 $use_v3 = true; 40 } else { 41 $error_msg = is_wp_error($response) ? $response->get_error_message() : 'HTTP ' . $status_code; 42 $this->plugin->log_event('AIB Network Sync: V3 failed (' . $error_msg . '), falling back to V2.', 'warning'); 43 } 44 } 45 46 // FALLBACK V2 (Si no hay token o falló V3) 47 if (!$use_v3) { 48 $response = wp_remote_get($this->feed_url_v2, [ 49 'timeout' => 30 50 ]); 51 52 if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { 53 $error_msg = is_wp_error($response) ? $response->get_error_message() : 'HTTP ' . wp_remote_retrieve_response_code($response); 54 $this->plugin->log_event('AIB Network list download failed completely. Reason: ' . $error_msg, 'error'); 55 56 // Actualizar timestamp para no reintentar de inmediato 57 update_option(ADVAIPBL_Main::OPTION_COMMUNITY_SYNC_TIME, time()); 58 return false; 59 } 60 $feed_data = wp_remote_retrieve_body($response); 61 } 62 63 // Process the downloaded data 64 if (!$feed_data) { 65 $this->plugin->log_event('AIB Network list download failed: No data received from V3 or V2.', 'error'); 24 66 return false; 25 67 } 26 27 $body = wp_remote_retrieve_body($response); 28 $data = json_decode($body, true); 68 69 $data = json_decode($feed_data, true); 29 70 30 71 if (!$data || !isset($data['ips']) || !is_array($data['ips'])) { 72 $this->plugin->log_event('AIB Network list download failed: Invalid data format.', 'error'); 31 73 return false; 32 74 } … … 141 183 ]; 142 184 } 185 186 /** 187 * Registers the site with the Central Server and gets a V3 API Token. 188 * Can be called manually via AJAX or automatically during upgrades. 189 * 190 * @return array|WP_Error Returns an array with 'api_token' on success, or WP_Error on failure. 191 */ 192 public function register_site() { 193 $site_url = home_url(); 194 195 $response = wp_remote_post('https://advaipbl.com/wp-json/aib-api/v3/register', [ 196 'headers' => [ 197 'Content-Type' => 'application/json', 198 'Accept' => 'application/json' 199 ], 200 'body' => wp_json_encode(['site_url' => $site_url]), 201 'timeout' => 15 202 ]); 203 204 if (is_wp_error($response)) { 205 $this->plugin->log_event('Community Network Registration failed: ' . $response->get_error_message(), 'error'); 206 return new WP_Error('registration_failed', $response->get_error_message()); 207 } 208 209 $status_code = wp_remote_retrieve_response_code($response); 210 $body = json_decode(wp_remote_retrieve_body($response), true); 211 212 // Permitir continuar (o al menos loguear info útil) si hay rate-limit o ya registrado 213 if ($status_code !== 200) { 214 $error_msg = $body['message'] ?? __('Unknown error during registration.', 'advanced-ip-blocker'); 215 $this->plugin->log_event("Community Network Registration failed (HTTP {$status_code}): {$error_msg}", 'error'); 216 217 // If the key was already registered or there are too many requests, we don't abort the entire plugin, 218 // we just inform. Ideally, for a test environment, the admin should generate 219 // from their account or wait. 220 if ($status_code === 429 || (isset($body['code']) && $body['code'] === 'site_already_registered')) { 221 // For these specific cases, we might not return an error, but rather indicate it's handled. 222 // However, the function signature expects WP_Error on failure, so we'll return an error. 223 return new WP_Error('registration_failed_handled', $error_msg, ['status' => $status_code]); 224 } 225 return new WP_Error('registration_failed', $error_msg, ['status' => $status_code]); 226 } 227 228 if (isset($body['status']) && $body['status'] === 'success' && !empty($body['api_token'])) { 229 $options = $this->plugin->options; // Get current options 230 $options['api_token_v3'] = sanitize_text_field($body['api_token']); 231 update_option(ADVAIPBL_Main::OPTION_SETTINGS, $options); 232 $this->plugin->options = $options; // Update memory cache 233 234 return [ 235 'api_token' => $body['api_token'] 236 ]; 237 } 238 239 $error_msg = $body['message'] ?? __('Failed to generate API Key.', 'advanced-ip-blocker'); 240 return new WP_Error('registration_failed', $error_msg); 241 } 143 242 } -
advanced-ip-blocker/trunk/includes/class-advaipbl-main.php
r3476940 r3481949 181 181 add_filter('authenticate', [$this, 'check_login_rules'], 20, 3); 182 182 183 add_action(' plugins_loaded', [$this, 'check_database_update']);183 add_action('admin_init', [$this, 'check_database_update']); 184 184 $this->add_hooks(); 185 185 … … 260 260 add_action('wp_login_failed', [$this, 'registrar_intento_login_fallido']); 261 261 add_action('login_init', [ $this, 'handle_login_page_restriction' ], 1 ); 262 add_action('login_init', [ $this, 'handle_login_geo_restriction' ], 2 ); 262 263 add_action('wp_login', [$this, 'auto_whitelist_admin_on_login'], 10, 2); 263 264 add_filter('rest_endpoints', [ $this, 'disable_rest_api_user_endpoints' ] ); … … 321 322 add_action('wp_ajax_advaipbl_add_ip_to_whitelist', [$this->ajax_handler, 'ajax_add_ip_to_whitelist']); 322 323 add_action('wp_ajax_advaipbl_verify_api_key', [$this->ajax_handler, 'ajax_verify_api_key']); 324 add_action('wp_ajax_advaipbl_get_free_api_key', [$this->ajax_handler, 'ajax_get_free_api_key']); 323 325 add_action('wp_ajax_advaipbl_update_geoip_db', [$this->ajax_handler, 'ajax_update_geoip_db']); 324 326 add_action('wp_ajax_advaipbl_get_dashboard_stats', [$this->ajax_handler, 'ajax_get_dashboard_stats']); … … 377 379 } 378 380 } 381 382 /** 383 * Helper routine to automatically generate V3 API Tokens for users who 384 * already had the AIB Network activated in older versions. 385 */ 386 private function auto_migrate_v3_token() { 387 // Ensure options are freshly loaded since this runs early in init during updates 388 $this->options = get_option(self::OPTION_SETTINGS, []); 389 390 // If the user hasn't opted-in to the community network, do nothing (privacy first) 391 if (empty($this->options['enable_community_network'])) { 392 return; 393 } 394 395 // If they already have a V3 token, do nothing 396 if (!empty($this->options['api_token_v3'])) { 397 return; 398 } 399 400 // Trigger the internal site registration to generate keys and fetch the V3 token 401 if (isset($this->community_manager)) { 402 $this->community_manager->register_site(); 403 404 // Re-load options into memory as register_site() modifies the DB directly sometimes 405 $this->options = get_option(self::OPTION_SETTINGS, []); 406 } 407 } 379 408 380 409 /** … … 460 489 } 461 490 462 if (wp_is_json_request() && strpos($request_uri, '/telemetry/') === false && strpos($request_uri, '/aib-network/') === false && strpos($request_uri, '/aib-scanner/') === false ) {491 if (wp_is_json_request() && strpos($request_uri, '/telemetry/') === false && strpos($request_uri, '/aib-network/') === false && strpos($request_uri, '/aib-scanner/') === false && strpos($request_uri, '/aib-api/') === false) { 463 492 return; 464 493 } … … 593 622 $wpdb->insert($table_name, $data_to_log); 594 623 } 624 625 /** 626 * Purges all cache from popular caching plugins. 627 * Called when security settings or blocklists change to ensure immediate effect. 628 */ 629 public function purge_all_page_caches() { 630 // LiteSpeed Cache 631 if (has_action('litespeed_purge_all')) { 632 do_action('litespeed_purge_all'); 633 } elseif (defined('LSCWP_V')) { 634 do_action('litespeed_purge_all_hook'); 635 } 636 637 // WP Rocket 638 if (function_exists('rocket_clean_domain')) { 639 rocket_clean_domain(); 640 } 641 642 // W3 Total Cache 643 if (function_exists('w3tc_flush_all')) { 644 w3tc_flush_all(); 645 } 646 647 // WP Super Cache 648 if (function_exists('wp_cache_clear_cache')) { 649 wp_cache_clear_cache(); 650 } 651 652 // WP Fastest Cache 653 if (isset($GLOBALS['wp_fastest_cache']) && method_exists($GLOBALS['wp_fastest_cache'], 'deleteCache')) { 654 $GLOBALS['wp_fastest_cache']->deleteCache(true); 655 } 656 657 // Autoptimize 658 if (class_exists('autoptimizeCache')) { 659 autoptimizeCache::clearall(); 660 } 661 662 // SG Optimizer (SiteGround) 663 if (function_exists('sg_cachepress_purge_cache')) { 664 sg_cachepress_purge_cache(); 665 } 666 667 // Kinsta Cache 668 if (class_exists('Kinsta\Cache')) { 669 do_action('kinsta_purge_edge_cache'); 670 } 671 672 /* translators: %s: Type of action triggered. */ 673 $this->log_event(__('System page caches successfully flushed after a security update.', 'advanced-ip-blocker'), 'info', 'localhost'); 674 } 595 675 596 676 /** … … 2003 2083 } 2004 2084 } 2085 2086 /** 2087 * Handles the geo-restriction of the login page. 2088 * Hooked to 'login_init' with priority 2. 2089 */ 2090 public function handle_login_geo_restriction() { 2091 if ( ! empty( $this->options['login_restrict_countries'] ) && is_array( $this->options['login_restrict_countries'] ) ) { 2092 $client_ip = $this->get_client_ip(); 2093 2094 // Bypass logic: whitelisted IPs are always allowed 2095 if ( $this->is_whitelisted( $client_ip ) ) { 2096 return; 2097 } 2098 2099 // Fetch the location of the IP 2100 $location = $this->geolocation_manager->fetch_location( $client_ip ); 2101 $country_code = $location['country_code'] ?? ''; 2102 2103 // If the country is not found, or it's not in the allowed list, block it 2104 if ( empty($country_code) || ! in_array( $country_code, $this->options['login_restrict_countries'], true ) ) { 2105 2106 /* translators: 1: The IP address, 2: The Country Code */ 2107 $this->log_event( sprintf( __( 'Login access denied due to Geo-Blocking restrictions for IP %1$s (%2$s)', 'advanced-ip-blocker' ), $client_ip, empty($country_code) ? 'Unknown' : $country_code ), 'warning', ['ip' => $client_ip] ); 2108 2109 // Show a generic access denied message 2110 wp_die( 2111 esc_html__( 'Login access from your location is not allowed.', 'advanced-ip-blocker' ), 2112 esc_html__( 'Access Denied', 'advanced-ip-blocker' ), 2113 [ 'response' => 403 ] 2114 ); 2115 } 2116 } 2117 } 2005 2118 2006 2119 /** … … 2633 2746 // Valor por defecto '1.0' para instalaciones muy antiguas 2634 2747 $current_db_version = get_option('advaipbl_db_version', '1.0'); 2748 $installed_plugin_ver = get_option('advaipbl_version_installed', '0.0.0'); 2635 2749 2636 2750 // Si la versión guardada es menor que la versión actual del código ('1.9') … … 2662 2776 $this->log_event('Community list forced update during DB upgrade.', 'info'); 2663 2777 } 2778 } 2779 2780 // --- Migraciones de nueva generación basadas en Plugin Version --- 2781 if ( version_compare($installed_plugin_ver, ADVAIPBL_VERSION, '<') ) { 2782 2783 // Migración a 8.9.0: Auto-Generar Token V3 2784 if ( version_compare($installed_plugin_ver, '8.9.0', '<') && $installed_plugin_ver !== '0.0.0' ) { 2785 $this->auto_migrate_v3_token(); 2786 } 2787 2788 // Actualizar la versión instalada en la base de datos 2789 update_option('advaipbl_version_installed', ADVAIPBL_VERSION); 2664 2790 } 2665 2791 … … 5557 5683 * Se ejecuta a través de una tarea de WP-Cron. 5558 5684 */ 5559 public function send_telemetry_data() {5560 if (empty($this->options['allow_telemetry']) || '1' !== $this->options['allow_telemetry']) {5561 return;5562 }5563 5685 /** 5686 * Genera el payload de telemetría de uso del plugin. 5687 * @return array 5688 */ 5689 private function get_telemetry_payload() { 5564 5690 global $wpdb; 5565 5691 $is_woocommerce_active = class_exists('WooCommerce'); … … 5577 5703 'is_woo_active' => $is_woocommerce_active, 5578 5704 'geo_provider' => $this->options['geolocation_provider'] ?? 'N/A', 5579 'geolocation_method' => $this->options['geolocation_method'] ?? 'api',5705 'geolocation_method' => $this->options['geolocation_method'] ?? 'api', 5580 5706 ]; 5581 5707 … … 5589 5715 5590 5716 // Array de settings completo que refleja todos los módulos principales. 5591 // Las claves coinciden con las opciones reales para mayor claridad.5592 5717 $telemetry_data['settings'] = [ 5593 5718 'enable_waf' => !empty($this->options['enable_waf']), … … 5598 5723 'enable_spamhaus_asn' => !empty($this->options['enable_spamhaus_asn']), 5599 5724 'enable_manual_asn' => !empty($this->options['enable_manual_asn']), 5600 'enable_abuseipdb' => !empty($this->options['enable_abuseipdb']),5725 'enable_abuseipdb' => !empty($this->options['enable_abuseipdb']), 5601 5726 'xmlrpc_protection_mode' => $this->options['xmlrpc_protection_mode'] ?? 'smart', 5602 5727 'recaptcha_enable' => !empty($this->options['recaptcha_enable']), 5603 5728 'enable_push_notifications' => !empty($this->options['enable_push_notifications']), 5604 'enable_threat_scoring' => !empty($this->options['enable_threat_scoring']),5605 'auto_whitelist_admin' => !empty($this->options['auto_whitelist_admin']),5729 'enable_threat_scoring' => !empty($this->options['enable_threat_scoring']), 5730 'auto_whitelist_admin' => !empty($this->options['auto_whitelist_admin']), 5606 5731 'disable_user_enumeration' => !empty($this->options['disable_user_enumeration']), 5607 5732 'prevent_author_scanning' => !empty($this->options['prevent_author_scanning']), 5608 5733 'restrict_login_page' => !empty($this->options['restrict_login_page']), 5609 'prevent_login_hinting' => !empty($this->options['prevent_login_hinting']),5610 'enable_email_notifications' => !empty($this->options['enable_email_notifications']),5611 'enable_signature_engine' => !empty($this->options['enable_signature_engine']),5734 'prevent_login_hinting' => !empty($this->options['prevent_login_hinting']), 5735 'enable_email_notifications' => !empty($this->options['enable_email_notifications']), 5736 'enable_signature_engine' => !empty($this->options['enable_signature_engine']), 5612 5737 'enable_signature_analysis' => !empty($this->options['enable_signature_analysis']), 5613 5738 'enable_signature_blocking' => !empty($this->options['enable_signature_blocking']), 5614 'enable_2fa' => !empty($this->options['enable_2fa']),5615 'enable_xmlrpc_lockdown' => !empty($this->options['enable_xmlrpc_lockdown']),5739 'enable_2fa' => !empty($this->options['enable_2fa']), 5740 'enable_xmlrpc_lockdown' => !empty($this->options['enable_xmlrpc_lockdown']), 5616 5741 'enable_login_lockdown' => !empty($this->options['enable_login_lockdown']), 5617 5742 'enable_404_lockdown' => !empty($this->options['enable_404_lockdown']), … … 5621 5746 'enable_audit_log' => !empty($this->options['enable_audit_log']), 5622 5747 'enable_fim' => !empty($this->options['enable_fim']), 5623 5624 'enable_bot_verification' => !empty($this->options['enable_bot_verification']), 5625 'enable_geo_challenge' => !empty($this->options['enable_geo_challenge']), 5748 'enable_bot_verification' => !empty($this->options['enable_bot_verification']), 5749 'enable_geo_challenge' => !empty($this->options['enable_geo_challenge']), 5626 5750 'htaccess_write' => !empty($this->options['enable_htaccess_write']), 5627 5751 'htaccess_sync_ips' => !empty($this->options['enable_htaccess_ip_blocking']), … … 5630 5754 'htaccess_hardening_config' => !empty($this->options['htaccess_protect_wp_config']), 5631 5755 'htaccess_hardening_readme' => !empty($this->options['htaccess_protect_readme']), 5632 'cloudflare_enabled' => !empty($this->options['enable_cloudflare']),5756 'cloudflare_enabled' => !empty($this->options['enable_cloudflare']), 5633 5757 'cloudflare_sync_manual' => !empty($this->options['cf_sync_manual']), 5634 5758 'cloudflare_sync_temp' => !empty($this->options['cf_sync_temporary']), … … 5664 5788 'ips_with_active_score' => (int) $wpdb->get_var("SELECT COUNT(id) FROM {$wpdb->prefix}advaipbl_ip_scores"), 5665 5789 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 5666 'active_malicious_signatures' => (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM {$wpdb->prefix}advaipbl_malicious_signatures WHERE expires_at > %d", time())),5790 'active_malicious_signatures' => (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM {$wpdb->prefix}advaipbl_malicious_signatures WHERE expires_at > %d", time())), 5667 5791 'geo_challenge_country_count' => count($this->options['geo_challenge_countries'] ?? []), 5668 ];5792 ]; 5669 5793 5670 5794 $server_ip = $this->get_server_ip(); … … 5675 5799 } 5676 5800 } 5801 5802 return $telemetry_data; 5803 } 5804 5805 /** 5806 * Recopila y envía datos de telemetría anónimos a un endpoint de API REST. 5807 * Se ejecuta a través de una tarea de WP-Cron. 5808 */ 5809 public function send_telemetry_data() { 5810 if (empty($this->options['allow_telemetry']) || '1' !== $this->options['allow_telemetry']) { 5811 return; 5812 } 5813 5814 // Si tenemos V3 y participamos en la red comunitaria, la telemetría viaja incrustada 5815 // en 'execute_community_report' para ahorrar envíos. Se anula el envío V2 aislado. 5816 if (!empty($this->options['api_token_v3']) && !empty($this->options['enable_community_network'])) { 5817 return; 5818 } 5819 5820 $telemetry_data = $this->get_telemetry_payload(); 5677 5821 5678 5822 $endpoint_url = 'https://advaipbl.com/wp-json/telemetry/v2/submit'; 5679 5823 $secret_key = 'yV.vZRp|g6E{zJ,DI7WcMIiGDejmH($$~<0-I$$Bd7Y) D5Z65M/*P:h>w:/E<D<'; 5824 5825 $headers = [ 5826 'Content-Type' => 'application/json', 5827 'X-Telemetry-Key' => $secret_key 5828 ]; 5829 5830 // Incluir Token V3 como fallback si llegara aquí, aunque V3 debe saltar arriba. 5831 if (!empty($this->options['api_token_v3'])) { 5832 $headers['Authorization'] = 'Bearer ' . $this->options['api_token_v3']; 5833 } 5680 5834 5681 5835 wp_remote_post($endpoint_url, [ 5682 5836 'timeout' => 15, 5683 5837 'blocking' => false, 5684 'headers' => [ 5685 'Content-Type' => 'application/json', 5686 'X-Telemetry-Key' => $secret_key 5687 ], 5838 'headers' => $headers, 5688 5839 'body' => wp_json_encode($telemetry_data), 5689 5840 ]); … … 5724 5875 'api_key_ipapicom', 'api_key_ipstackcom', 'api_key_ipinfocom', 5725 5876 'api_key_ip_apicom', 'maxmind_license_key', 'push_webhook_urls', 5726 'cf_api_token', 'cf_zone_id', 'abuseipdb_api_key' 5877 'cf_api_token', 'cf_zone_id', 'abuseipdb_api_key', 'api_token_v3' 5727 5878 ]; 5728 5879 foreach ($sensitive_keys as $sensitive_key) { … … 6933 7084 public function maybe_redirect_to_wizard() { 6934 7085 if ( get_option( 'advaipbl_run_setup_wizard' ) ) { 6935 // Eliminamos la opción para que no se redirija en bucle 7086 7087 // Evitar bucles infinitos en servidores con Object Caches muy lentos (ej. LiteSpeed) 7088 // comprobando si YA estamos en la ruta de destino. 7089 $is_already_on_wizard = ( isset( $_GET['page'] ) && $_GET['page'] === 'advaipbl-setup-wizard' ); 7090 6936 7091 delete_option( 'advaipbl_run_setup_wizard' ); 6937 7092 6938 if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_GET['activate-multi'] ) ) { 6939 // Si es una activación masiva, volvemos a añadir la opción para que se muestre el aviso. 6940 add_option( 'advaipbl_run_setup_wizard', true ); 7093 if ( $is_already_on_wizard || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_GET['activate-multi'] ) ) { 7094 // Si es activación masiva, volvemos a poner para mostrar mensaje. 7095 if ( isset( $_GET['activate-multi'] ) ) { 7096 add_option( 'advaipbl_run_setup_wizard', true ); 7097 } 6941 7098 return; 6942 7099 } 7100 6943 7101 wp_safe_redirect( admin_url( 'admin.php?page=advaipbl-setup-wizard' ) ); 6944 7102 exit; … … 7214 7372 } 7215 7373 7216 /**7374 /** 7217 7375 * Ejecuta el envío de reportes a la API central. 7218 7376 */ 7219 7377 public function execute_community_report() { 7220 // 1. Verificar si el usuario participa 7378 // 1. Obtener el lote de bloqueos (solo si participa en AIB Network) 7379 $payload = [ 7380 'site_hash' => hash('sha256', home_url()), 7381 'version' => ADVAIPBL_VERSION, 7382 'reports' => [] 7383 ]; 7384 7385 global $wpdb; 7221 7386 if ( empty($this->options['enable_community_network']) ) { 7222 // Si no participa, limpiamos la tabla local para no acumular basura 7223 global $wpdb; 7387 // Si no participa en red, no enviamos reportes de amenazas (pero la telemetria puede enviarse abajo) 7224 7388 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 7225 7389 $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}advaipbl_pending_reports"); 7226 return; 7227 } 7228 7229 // 2. Obtener el lote 7230 $payload = $this->reporter_manager->get_batch_for_api(100); // 100 reportes por envío 7231 7232 if ( empty($payload['reports']) ) { 7233 return; // Nada que enviar 7234 } 7235 7236 // 3. Enviar a la API (V2 con strict anti-poisoning) 7237 $api_url = 'https://advaipbl.com/wp-json/aib-network/v2/report'; 7238 7239 // La API V2 requiere el site_hash explicitamente en el root del JSON para aplicar el Rate Limiting local 7390 } else { 7391 $gathered_payload = $this->reporter_manager->get_batch_for_api(100); 7392 if (!empty($gathered_payload)) { 7393 $payload = $gathered_payload; 7394 } 7395 } 7396 7397 $has_reports = !empty($payload['reports']); 7398 7399 $has_v3_token = !empty($this->options['api_token_v3']); 7400 7401 // 3. Fallback a V2 si no hay token V3 (V2 no agrupa telemetría, aborta si no hay reportes) 7402 if (!$has_v3_token && !$has_reports) { 7403 return; 7404 } 7405 7406 // Asegurar site_hash para Rate Limiting V2 o info cruda 7240 7407 $payload_data = $payload; 7241 7408 $payload_data['site_hash'] = $payload['site_hash'] ?? hash('sha256', get_site_url()); 7242 7409 7410 // 4. Parámetros de envío 7411 if ($has_v3_token) { 7412 $api_url = 'https://advaipbl.com/wp-json/aib-api/v3/report'; 7413 $headers = [ 7414 'Content-Type' => 'application/json', 7415 'Authorization' => 'Bearer ' . $this->options['api_token_v3'] 7416 ]; 7417 7418 // En V3 inyectamos la telemetría general en el mismo paquete para ahorrar recursos del cliente y servidor 7419 if (!empty($this->options['allow_telemetry']) && '1' === $this->options['allow_telemetry']) { 7420 $payload_data['telemetry'] = $this->get_telemetry_payload(); 7421 } else { 7422 $payload_data['telemetry'] = []; 7423 } 7424 7425 // Si después de intentarlo no hay ni amenazas locales ni métricas permitidas, no saturamos la red 7426 if (!$has_reports && empty($payload_data['telemetry'])) { 7427 return; 7428 } 7429 7430 } else { 7431 // Configuración V2 (Asegurar que nunca llegamos aquí si !$has_reports por la comprobación anterior) 7432 $api_url = 'https://advaipbl.com/wp-json/aib-network/v2/report'; 7433 $headers = [ 7434 'Content-Type' => 'application/json', 7435 'X-AIB-Site-Hash' => $payload_data['site_hash'], 7436 ]; 7437 } 7438 7243 7439 $response = wp_remote_post( $api_url, [ 7244 'body' => wp_json_encode($payload_data), 7245 'headers' => [ 7246 'Content-Type' => 'application/json', 7247 'X-AIB-Site-Hash' => $payload_data['site_hash'], // Cabecera de autenticación simple 7248 ], 7249 'timeout' => 10, 7250 'blocking' => false // "Fire and forget" para no ralentizar el cron 7440 'body' => wp_json_encode($payload_data), 7441 'headers' => $headers, 7442 'timeout' => 5, 7443 'blocking' => false 7251 7444 ]); 7252 7253 if ( is_wp_error($response) ) {7254 // Loguear error silenciosamente para debug7255 // error_log('AIB Network Report Failed: ' . $response->get_error_message());7256 }7257 7445 } 7258 7446 -
advanced-ip-blocker/trunk/includes/class-advaipbl-settings-manager.php
r3464093 r3481949 41 41 add_settings_field('advaipbl_show_admin_bar_menu', __( 'Admin Bar Menu', 'advanced-ip-blocker' ), [$this, 'switch_field_callback'], $page, 'advaipbl_general_settings_section', ['name' => 'show_admin_bar_menu', 'label' => __( 'Show security menu in the WordPress admin bar', 'advanced-ip-blocker' )]); 42 42 43 44 43 45 add_settings_section('advaipbl_general_settings_section', null, null, $page); 44 46 add_settings_field( … … 229 231 // --- AIB COMMUNITY NETWORK SECTION --- 230 232 add_settings_section('advaipbl_community_network_section', null, null, $page); 233 234 // --- V3 API Connection --- 235 add_settings_field( 236 'advaipbl_api_connection_status', 237 __('AIB Account Connection', 'advanced-ip-blocker'), 238 [$this, 'api_connection_status_callback'], 239 $page, 240 'advaipbl_community_network_section' 241 ); 242 243 add_settings_field( 244 'advaipbl_api_token_v3', 245 __('API Token', 'advanced-ip-blocker'), 246 [$this, 'api_token_field_callback'], 247 $page, 248 'advaipbl_community_network_section', 249 [ 250 'name' => 'api_token_v3', 251 'description' => __('Connecting to the Advanced IP Blocker cloud network gives you access to the community blocklist and deep site scanning.', 'advanced-ip-blocker'), 252 ] 253 ); 231 254 232 255 add_settings_field( … … 475 498 ); 476 499 add_settings_field('advaipbl_restrict_login_page', __( 'Whitelist Login Access', 'advanced-ip-blocker' ), [ $this, 'restrict_login_page_callback' ], $page, 'advaipbl_advanced_login_section'); 500 501 add_settings_field('advaipbl_login_restrict_countries', __( 'Whitelist Login Countries', 'advanced-ip-blocker' ), [ $this, 'geoblock_countries_callback' ], $page, 'advaipbl_advanced_login_section', [ 502 'type' => 'login_restrict', 503 'description' => __('Select one or more countries that are allowed to access wp-login.php. If empty, all countries are allowed.', 'advanced-ip-blocker') 504 ]); 505 477 506 add_settings_section('advaipbl_advanced_xmlrpc_section', null, null, $page); 478 507 add_settings_field('advaipbl_xmlrpc_protection_mode', __('XML-RPC Protection Mode', 'advanced-ip-blocker'), [$this, 'xmlrpc_protection_mode_callback'], $page, 'advaipbl_advanced_xmlrpc_section'); … … 1021 1050 'xmlrpc_protection_mode', 'geolocation_method', 'trusted_proxies', 'abuseipdb_api_key', 'abuseipdb_action', 1022 1051 'cf_api_token', 'cf_zone_id', 'community_blocking_action', 'scan_frequency', 'scan_notification_email', 1023 'fim_alert_email' 1052 'fim_alert_email', 'api_token_v3' 1024 1053 ]; 1025 1054 … … 1043 1072 } 1044 1073 1074 // V3 API Token Validation (only if changed manually) 1075 if (isset($new_input['api_token_v3']) && $new_input['api_token_v3'] !== ($this->plugin->options['api_token_v3'] ?? '')) { 1076 if (!empty($new_input['api_token_v3'])) { 1077 $response = wp_remote_get('https://advaipbl.com/wp-json/aib-api/v3/verify-token', [ 1078 'headers' => [ 1079 'Authorization' => 'Bearer ' . $new_input['api_token_v3'], 1080 'Accept' => 'application/json' 1081 ], 1082 'timeout' => 15 1083 ]); 1084 1085 if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { 1086 add_settings_error('advaipbl_settings_messages', 'invalid_v3_token', __('Invalid AIB Cloud Network Token. Connection failed.', 'advanced-ip-blocker'), 'error'); 1087 $new_input['api_token_v3'] = $this->plugin->options['api_token_v3'] ?? ''; // Revert to previous or empty 1088 } 1089 } 1090 } 1091 1045 1092 if (isset($input['geoblock_countries'])) { 1046 1093 $countries = (array) $input['geoblock_countries']; … … 1058 1105 $new_input['geo_challenge_countries'] = []; 1059 1106 } 1107 1108 if (isset($input['login_restrict_countries'])) { 1109 $countries = (array) $input['login_restrict_countries']; 1110 $all_country_codes = array_keys($this->plugin->get_country_list()); 1111 $new_input['login_restrict_countries'] = array_values(array_intersect($countries, $all_country_codes)); 1112 } else { 1113 $new_input['login_restrict_countries'] = []; 1114 } 1060 1115 1061 1116 if (isset($input['recaptcha_score_threshold'])) { 1062 1117 $new_input['recaptcha_score_threshold'] = $this->plugin->sanitize_score_threshold($input['recaptcha_score_threshold']); 1063 1118 } 1119 1120 // Purge page caches when security settings are updated 1121 $this->plugin->purge_all_page_caches(); 1064 1122 1065 1123 return $new_input; … … 1409 1467 } 1410 1468 } 1469 1470 /** 1471 * Callback para mostrar el estado de la conexión con la API V3. 1472 */ 1473 public function api_connection_status_callback() { 1474 $token = $this->plugin->options['api_token_v3'] ?? ''; 1475 1476 if (empty($token)) { 1477 echo '<span class="dashicons dashicons-dismiss" style="color: #d63638;"></span> <strong style="color: #d63638;">' . esc_html__('Not Connected', 'advanced-ip-blocker') . '</strong>'; 1478 echo '<p class="description">' . esc_html__('Get a Free API Key below to connect your site to the AIB Cloud Network.', 'advanced-ip-blocker') . '</p>'; 1479 } else { 1480 echo '<div id="advaipbl-api-status-container">'; 1481 echo '<span class="dashicons dashicons-yes-alt" style="color: #00a32a;"></span> <strong style="color: #00a32a;">' . esc_html__('Connected', 'advanced-ip-blocker') . '</strong>'; 1482 1483 // Si tuviéramos el tipo de plan guardado, lo mostraríamos aquí. Por ahora, asumimos conectado. 1484 echo ' <span class="advaipbl-badge advaipbl-badge-free" style="margin-left:5px;">' . esc_html__('AIB Cloud Network', 'advanced-ip-blocker') . '</span>'; 1485 1486 echo '<p class="description" style="margin-top:5px;">'; 1487 echo '<button type="button" class="button button-secondary button-small" id="advaipbl-verify-api-token">' . esc_html__('Verify Connection', 'advanced-ip-blocker') . '</button>'; 1488 echo '<span id="advaipbl-api-verification-result" style="margin-left: 8px;"></span>'; 1489 echo '</p>'; 1490 echo '</div>'; 1491 } 1492 } 1493 1494 /** 1495 * Callback específico para el campo del Token API con ofuscación. 1496 */ 1497 public function api_token_field_callback($args) { 1498 $name = $args['name']; 1499 $value = isset($this->plugin->options[$name]) ? $this->plugin->options[$name] : ''; 1500 1501 // Ofuscar si existe 1502 $display_val = $value; 1503 if (!empty($value) && strlen($value) > 8) { 1504 $display_val = substr($value, 0, 4) . str_repeat('•', 24) . substr($value, -4); 1505 } 1506 1507 echo '<div style="display: flex; gap: 10px; position: relative; align-items: center;">'; 1508 1509 echo '<div style="display: flex; gap: 10px; max-width: 400px; position: relative; align-items: center;">'; 1510 1511 // Campo visible al usuario (puede estar ofuscado si ya hay valor) 1512 echo '<input type="text" id="advaipbl_' . esc_attr($name) . '_display" class="regular-text" style="font-family: monospace;" '; 1513 if (!empty($value)) { 1514 echo 'value="' . esc_attr($display_val) . '" disabled'; 1515 echo '>'; 1516 // Campo oculto real que se enviará en el formulario POST sólo si no se edita 1517 echo '<input type="hidden" name="' . esc_attr(ADVAIPBL_Main::OPTION_SETTINGS) . '[' . esc_attr($name) . ']" id="advaipbl_' . esc_attr($name) . '" value="' . esc_attr($value) . '">'; 1518 // Botón para editar 1519 echo '<button type="button" class="button" id="advaipbl-edit-api-token" title="' . esc_attr__('Edit API Key', 'advanced-ip-blocker') . '"><span class="dashicons dashicons-edit" style="margin-top: 2px;"></span></button>'; 1520 } else { 1521 // Si no hay valor, lo mostramos normal como input type="text" pero que envía 1522 echo 'name="' . esc_attr(ADVAIPBL_Main::OPTION_SETTINGS) . '[' . esc_attr($name) . ']" id="advaipbl_' . esc_attr($name) . '" value="" placeholder="AIB_xxxxxxxxxxxxxxxxxxxxxxxxxx">'; 1523 // Botón mágico para generar clave 1524 echo '<button type="button" class="button button-primary" id="advaipbl-get-api-token" title="' . esc_attr__('Get a Free VIP Key instantly', 'advanced-ip-blocker') . '">' . esc_html__('Get Free Key', 'advanced-ip-blocker') . '</button>'; 1525 echo '<span class="spinner" id="advaipbl-api-token-spinner" style="float:none; margin:0;"></span>'; 1526 } 1527 1528 echo '</div>'; 1529 1530 if (isset($args['description']) && empty($value)) { 1531 echo '<p class="description" style="margin-top:5px;">' . wp_kses_post($args['description']) . '</p>'; 1532 } else if (!empty($value)) { 1533 echo '<p class="description" style="margin-top:5px;">' . esc_html__('Your API key is hidden for security.', 'advanced-ip-blocker') . '</p>'; 1534 } 1535 1536 // Script para manejar la edición y la validación 1537 ?> 1538 <script> 1539 jQuery(document).ready(function($) { 1540 $('#advaipbl-edit-api-token').on('click', function(e) { 1541 e.preventDefault(); 1542 var $display = $('#advaipbl_<?php echo esc_js($name); ?>_display'); 1543 var $hidden = $('#advaipbl_<?php echo esc_js($name); ?>'); 1544 1545 // Convert display to a real input field connected to POST 1546 $display.prop('disabled', false) 1547 .val('') 1548 .attr('name', '<?php echo esc_js(ADVAIPBL_Main::OPTION_SETTINGS); ?>[<?php echo esc_js($name); ?>]') 1549 .focus(); 1550 1551 // Remove hidden field and button 1552 $hidden.remove(); 1553 $(this).remove(); 1554 }); 1555 1556 // Validación simple del lado del cliente antes de enviar 1557 $('form').on('submit', function() { 1558 var apiTokenInput = $('input[name="<?php echo esc_js(ADVAIPBL_Main::OPTION_SETTINGS); ?>[<?php echo esc_js($name); ?>]"]'); 1559 if (apiTokenInput.length && !apiTokenInput.prop('disabled')) { 1560 var val = apiTokenInput.val().trim(); 1561 if (val !== '' && !val.startsWith('AIB_')) { 1562 alert('<?php echo esc_js(__('Invalid API Key format. It should start with AIB_.', 'advanced-ip-blocker')); ?>'); 1563 apiTokenInput.focus(); 1564 return false; 1565 } 1566 } 1567 return true; 1568 }); 1569 }); 1570 </script> 1571 <?php 1572 } 1411 1573 /** 1412 1574 * Muestra el campo <select> para el modo de protección XML-RPC. … … 1450 1612 $type = $args['type'] ?? 'geoblock'; // Por defecto es geoblock para retrocompatibilidad 1451 1613 1452 $option_name = ($type === 'geo_challenge') ? 'geo_challenge_countries' : 'geoblock_countries'; 1614 if ($type === 'geo_challenge') { 1615 $option_name = 'geo_challenge_countries'; 1616 $placeholder_text = __('Search for a country to challenge...', 'advanced-ip-blocker'); 1617 } elseif ($type === 'login_restrict') { 1618 $option_name = 'login_restrict_countries'; 1619 $placeholder_text = __('Search for an allowed country...', 'advanced-ip-blocker'); 1620 } else { 1621 $option_name = 'geoblock_countries'; 1622 $placeholder_text = __('Search for a country to block...', 'advanced-ip-blocker'); 1623 } 1624 1453 1625 $select_id = 'advaipbl_' . $option_name; 1454 $placeholder_text = ($type === 'geo_challenge')1455 ? __('Search for a country to challenge...', 'advanced-ip-blocker')1456 : __('Search for a country to block...', 'advanced-ip-blocker');1457 1626 1458 1627 $selected_countries = $this->plugin->options[$option_name] ?? []; … … 1466 1635 <?php endforeach; ?> 1467 1636 </select> 1468 <p class="description"> 1469 <?php esc_html_e( 'Select one or more countries. Type in the box to search.', 'advanced-ip-blocker' ); ?> 1470 </p> 1637 <?php if (isset($args['description'])) : ?> 1638 <p class="description"><?php echo wp_kses_post($args['description']); ?></p> 1639 <?php else : ?> 1640 <p class="description"> 1641 <?php esc_html_e( 'Select one or more countries. Type in the box to search.', 'advanced-ip-blocker' ); ?> 1642 </p> 1643 <?php endif; ?> 1471 1644 <?php 1472 1645 } -
advanced-ip-blocker/trunk/includes/class-advaipbl-site-scanner.php
r3469306 r3481949 237 237 $site_hash = hash('sha256', get_site_url()); 238 238 239 $headers = [ 240 'Content-Type' => 'application/json', 241 'X-AIB-Site-Hash' => $site_hash 242 ]; 243 244 // Incluir V3 Token y saltar a endpoint V3 si existe 245 if (!empty($this->plugin->options['api_token_v3'])) { 246 $api_url = 'https://advaipbl.com/wp-json/aib-api/v3/scanner/check'; 247 $headers['Authorization'] = 'Bearer ' . $this->plugin->options['api_token_v3']; 248 } 249 239 250 $response = wp_remote_post( $api_url, [ 240 251 'body' => wp_json_encode( $payload ), 241 'headers' => [ 242 'Content-Type' => 'application/json', 243 'X-AIB-Site-Hash' => $site_hash 244 ], 252 'headers' => $headers, 245 253 'timeout' => 15 // Subimos un poco el timeout por si la lista es larga 246 254 ]); … … 290 298 $api_check_url = 'https://advaipbl.com/wp-json/aib-scanner/v2/check-ip?ip=' . $server_ip; 291 299 $site_hash = hash('sha256', get_site_url()); 300 301 $headers = [ 302 'X-AIB-Site-Hash' => $site_hash 303 ]; 304 305 // Incluir V3 Token y saltar a endpoint V3 si existe 306 if (!empty($this->plugin->options['api_token_v3'])) { 307 $api_check_url = 'https://advaipbl.com/wp-json/aib-api/v3/scanner/check-ip?ip=' . $server_ip; 308 $headers['Authorization'] = 'Bearer ' . $this->plugin->options['api_token_v3']; 309 } 292 310 293 311 $response = wp_remote_get($api_check_url, [ 294 312 'timeout' => 5, 295 'headers' => [ 296 'X-AIB-Site-Hash' => $site_hash 297 ] 313 'headers' => $headers 298 314 ]); 299 315 -
advanced-ip-blocker/trunk/js/admin-settings.js
r3455663 r3481949 561 561 }); 562 562 }); 563 564 // Handler específico para el Token API V3 565 $('body').on('click', '#advaipbl-verify-api-token', function (e) { 566 e.preventDefault(); 567 const $button = $(this); 568 // El selector del token V3 ahora usa _display o el input oculto tras darle a editar 569 let apiKey = $('#advaipbl_api_token_v3_display').val() || $('#advaipbl_api_token_v3').val(); 570 const $statusContainer = $button.closest('.advaipbl-status-indicator'); 571 const texts = adminData.text || {}; 572 573 $button.text(texts.verifying_api || 'Verifying...').prop('disabled', true); 574 575 if (!apiKey || apiKey.indexOf('•') !== -1) { // If it's obfuscated, we just grab the real one 576 apiKey = $('#advaipbl_api_token_v3').val(); 577 } 578 579 if (!apiKey) { 580 showAdminNotice(texts.enter_api_key || 'Please enter an API key first.', 'error'); 581 $button.text('Verify Connection').prop('disabled', false); 582 return; 583 } 584 585 $.post(ajaxurl, { 586 action: 'advaipbl_verify_api_key', 587 nonce: adminData.nonces.verify_api, 588 provider: 'api_token_v3', 589 api_key: apiKey 590 }) 591 .done(function (response) { 592 const $resultSpan = $('#advaipbl-api-verification-result'); 593 if (response.success) { 594 $resultSpan.text(response.data.message).css({ 'color': 'green', 'font-weight': 'bold' }); 595 $button.text('Verify Connection'); 596 } else { 597 $resultSpan.text('Error: ' + response.data.message).css({ 'color': 'red', 'font-weight': 'bold' }); 598 $button.text('Verify Connection'); 599 } 600 }) 601 .fail(function () { 602 const $resultSpan = $('#advaipbl-api-verification-result'); 603 $resultSpan.text(texts.ajax_error || 'AJAX error.').css({ 'color': 'red', 'font-weight': 'bold' }); 604 $button.text('Verify Connection'); 605 }) 606 .always(function () { 607 $button.prop('disabled', false); 608 }); 609 }); 610 611 // Handler para generar una clave gratuita (In-App Registration) 612 $('body').on('click', '#advaipbl-get-api-token', function (e) { 613 e.preventDefault(); 614 const $button = $(this); 615 const $spinner = $('#advaipbl-api-token-spinner'); 616 const originalText = $button.text(); 617 618 $button.prop('disabled', true).text('Generating...'); 619 $spinner.addClass('is-active'); 620 621 $.post(ajaxurl, { 622 action: 'advaipbl_get_free_api_key', 623 nonce: adminData.nonces.verify_api, // Reutilizamos el nonce de ajustes generales 624 _t: Date.now() // Cache buster para Cloudflare 625 }) 626 .done(function (response) { 627 if (response.success) { 628 showAdminNotice(response.data.message, 'success'); 629 // Actualizar el valor visual localmente sin recargar 630 const newHtml = ` 631 <input type="text" id="advaipbl_api_token_v3_display" class="regular-text" style="font-family: monospace;" value="${response.data.api_token_visual}" disabled> 632 <input type="hidden" name="advaipbl_settings[api_token_v3]" id="advaipbl_api_token_v3" value="${response.data.api_token}"> 633 <button type="button" class="button" id="advaipbl-edit-api-token" title="Edit API Key"><span class="dashicons dashicons-edit" style="margin-top: 2px;"></span></button> 634 `; 635 // Recargar suavemente para asegurar que todo WordPress capte el Token V3 en backend sin error 636 // Eliminado reload automático para no perder el token sin guardar. 637 // setTimeout(() => window.location.reload(), 2000); 638 639 // En su lugar, actualizamos el texto de validación también 640 $('#advaipbl-api-verification-result').html('<span style="color: green;">' + (adminData.text.api_key_generated || 'API Key Generated!') + '</span>'); 641 642 // Localizar el indicador de estado de la red AIB y cambiarlo a activo visualmente 643 var $statusIndicator = $('.advaipbl-status-indicator'); 644 if($statusIndicator.length) { 645 $statusIndicator.css({ 646 'background': '#f0f6fc', 647 'border': '1px solid #cce5ff' 648 }); 649 $statusIndicator.html('<span class="dashicons dashicons-cloud-saved" style="color: #2271b1; vertical-align: middle;"></span> <strong>' + (adminData.text.protection_active || 'Protection Active:') + '</strong> <span style="margin-left:5px;">Connected (Waiting for first sync)</span>'); 650 } else { 651 // Si estaba 'Not Connected', no existe el div con esa clase, así que lo inyectamos 652 var $card = $button.closest('.advaipbl-card'); 653 var $header = $card.find('h3').first(); 654 $header.after('<div class="advaipbl-status-indicator" style="margin-bottom: 15px; padding: 10px; background: #f0f6fc; border: 1px solid #cce5ff; border-radius: 4px;"><span class="dashicons dashicons-cloud-saved" style="color: #2271b1; vertical-align: middle;"></span> <strong>' + (adminData.text.protection_active || 'Protection Active:') + '</strong> <span style="margin-left:5px;">Connected (Waiting for first sync)</span></div>'); 655 // Si hay un texto de 'No Conectado' previo en la tabla, podríamos querer ocultarlo 656 $card.find('td:contains("Not Connected"), td:contains("No Conectado")').html('<span style="color:green; font-weight:bold;">' + (adminData.text.connected || 'Connected') + '</span>'); 657 } 658 } else { 659 showAdminNotice('Error: ' + response.data.message, 'error'); 660 $button.prop('disabled', false).text(originalText); 661 $spinner.removeClass('is-active'); 662 } 663 }) 664 .fail(function () { 665 showAdminNotice(adminData.text.ajax_error || 'AJAX error.', 'error'); 666 $button.prop('disabled', false).text(originalText); 667 $spinner.removeClass('is-active'); 668 }); 669 }); 563 670 } 564 671 -
advanced-ip-blocker/trunk/languages/advanced-ip-blocker-es_ES.po
r3471934 r3481949 5 5 "blocker\n" 6 6 "POT-Creation-Date: 2025-07-22 14:47+0200\n" 7 "PO-Revision-Date: 2026-03- 01 08:26+0100\n"7 "PO-Revision-Date: 2026-03-11 11:29+0100\n" 8 8 "Last-Translator: \n" 9 9 "Language-Team: \n" … … 1590 1590 msgid "ASN blocklist saved successfully." 1591 1591 msgstr "Lista de bloqueo de ASN guardada exitosamente." 1592 1593 #: includes/class-advaipbl-settings-manager.php:501 1594 msgid "Whitelist Login Countries" 1595 msgstr "Países de inicio de sesión en la lista blanca" 1596 1597 #: includes/class-advaipbl-settings-manager.php:1210 1598 msgid "" 1599 "Select one or more countries that are allowed to access wp-login.php. If " 1600 "empty, all countries are allowed." 1601 msgstr "" 1602 "Seleccione uno o más países con permiso para acceder a wp-login.php. Si deja " 1603 "el campo vacío, se permite el acceso a todos los países." 1604 1605 #: includes/class-advaipbl-settings-manager.php:1434 1606 msgid "AIB Account Connection" 1607 msgstr "Conexión de cuenta AIB" 1608 1609 #: includes/class-advaipbl-settings-manager.php:1435 1610 msgid "Not Connected" 1611 msgstr "No Conectado" 1612 1613 #: includes/class-advaipbl-settings-manager.php:1436 1614 msgid "Get a Free API Key below to connect your site to the AIB Cloud Network." 1615 msgstr "" 1616 "Obtenga una clave API gratuita a continuación para conectar su sitio a la " 1617 "red en la nube de AIB." 1618 1619 #: includes/class-advaipbl-settings-manager.php:1437 1620 msgid "API Token" 1621 msgstr "API Token" 1622 1623 #: includes/class-advaipbl-settings-manager.php:1438 1624 msgid "Get Free Key" 1625 msgstr "Obtener clave gratis" 1626 1627 #: includes/class-advaipbl-settings-manager.php:1439 1628 msgid "" 1629 "Connecting to the Advanced IP Blocker cloud network gives you access to the " 1630 "community blocklist and deep site scanning." 1631 msgstr "" 1632 "Al conectarse a la red en la nube de Advanced IP Blocker, tendrá acceso a la " 1633 "lista de bloqueo de la comunidad y al escaneo profundo del sitio." 1592 1634 1593 1635 #: includes/class-advaipbl-main.php:3078 -
advanced-ip-blocker/trunk/languages/advanced-ip-blocker.pot
r3476940 r3481949 4 4 msgid "" 5 5 msgstr "" 6 "Project-Id-Version: Advanced IP Blocker 8. 8.9\n"6 "Project-Id-Version: Advanced IP Blocker 8.9.0\n" 7 7 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/advanced-ip-blocker\n" 8 8 "POT-Creation-Date: 2025-07-22 14:47+0200\n" … … 1415 1415 msgstr "" 1416 1416 1417 #: includes/class-advaipbl-settings-manager.php:501 1418 msgid "Whitelist Login Countries" 1419 msgstr "" 1420 1421 #: includes/class-advaipbl-settings-manager.php:1210 1422 msgid "Select one or more countries that are allowed to access wp-login.php. If empty, all countries are allowed." 1423 msgstr "" 1424 1425 #: includes/class-advaipbl-settings-manager.php:1434 1426 msgid "AIB Account Connection" 1427 msgstr "" 1428 1429 #: includes/class-advaipbl-settings-manager.php:1435 1430 msgid "Not Connected" 1431 msgstr "" 1432 1433 #: includes/class-advaipbl-settings-manager.php:1436 1434 msgid "Get a Free API Key below to connect your site to the AIB Cloud Network." 1435 msgstr "" 1436 1437 #: includes/class-advaipbl-settings-manager.php:1437 1438 msgid "API Token" 1439 msgstr "" 1440 1441 #: includes/class-advaipbl-settings-manager.php:1438 1442 msgid "Get Free Key" 1443 msgstr "" 1444 1445 #: includes/class-advaipbl-settings-manager.php:1439 1446 msgid "Connecting to the Advanced IP Blocker cloud network gives you access to the community blocklist and deep site scanning." 1447 msgstr "" 1448 1417 1449 #: includes/class-advaipbl-main.php:3078 1418 1450 #, php-format -
advanced-ip-blocker/trunk/readme.txt
r3476940 r3481949 6 6 Requires at least: 6.7 7 7 Tested up to: 6.9 8 Stable tag: 8. 8.98 Stable tag: 8.9.0 9 9 Requires PHP: 8.1 10 10 License: GPLv2 or later … … 21 21 22 22 **Key Features:** 23 * **(NEW) AIB Cloud Network V3:** Upgrade to the next-generation distributed threat intelligence network. The new API V3 provides secure, individual API Keys per site, drastically improving synchronization reliability, threat telemetry, and global network stability. 24 * **(NEW) Whitelist Login Countries:** Take absolute control over administrative access. Easily restrict your WordPress login page and XML-RPC to only allow connections from specific, whitelisted countries, instantly blocking unauthorized foreign login attempts. 23 25 * **(IMPROVED) Bulk Import/Export for Blocked IPs & Whitelist:** Seamlessly import massive lists of IPs via CSV or manual entry. The system now features a bulletproof "Bulk Import" type, strict duration inheritance, and intelligent conflict resolution. 24 26 * **(NEW) Internal Security & Forensics:** A complete audit suite solely for WordPress. Track every sensitive event (plugin installs, settings changes, user logins) and monitor your critical files for unauthorized modifications with the integrated File Integrity Monitor. … … 224 226 == Changelog == 225 227 228 = 8.9.0 = 229 * **NEW MAJOR FEATURE:** AIB Cloud Network V3. We've completely overhauled our Community Defense Network infrastructure. The new API V3 introduces secure, individual API Keys for every connected site, drastically improving synchronization reliability, security telemetry, and overall network stability. 230 * **NEW FEATURE:** Whitelist Login Countries. A highly requested feature! You can now explicitly select which countries are allowed to access your WordPress login page (`wp-login.php`) and XML-RPC, automatically blocking all other nations. 231 * **ENHANCEMENT:** Upgraded the "Verify Connection" UI for the Cloud Network to provide instant, inline diagnostic feedback (success/error) without page reloads. 232 * **CRITICAL FIX:** Resolved an issue where verifying an API key could trigger local 404 block rules due to an incorrect HTTP request method (POST instead of GET). 233 * **ROBUSTNESS:** Improved plugin uninstallation logic. When using the "Delete All Data" option, the plugin now seamlessly unregisters the local API Key from the Central Server to keep your account clean for future reinstallations. 234 * **ROBUSTNESS:** Prevented the automatic AIB Network protection list from getting stuck on "Downloading..." if an API key fails to generate due to rate limiting on a fresh install. 235 226 236 = 8.8.9 = 227 237 * **SECURITY UPDATE:** Fixed an issue where the "Export Template" feature was inadvertently including sensitive API keys (`cf_api_token`, `cf_zone_id`, `abuseipdb_api_key`) in the generated JSON. Templates are now completely clean of private tokens. … … 229 239 * **MAINTENANCE:** Analyzed and ensured that the background Cloudflare Sync task (`advaipbl_cloudflare_sync_event`) schedules properly. 230 240 231 = 8.8.8 =232 * **CRITICAL FIX:** Resolved an issue where IPs imported via the Bulk Import tool were not immediately synchronized with the Server-Level Firewall (`.htaccess`). Synchronization is now instantaneous and safely batched.233 * **CRITICAL FIX:** Addressed a regression introduced in the `.htaccess` fix where Cloudflare Edge Firewalls stopped synchronizing imported IPs. Bulk Imports will now immediately trigger a background Cloudflare Sync Event to safely upload large IP batches without dropping connections.234 235 = 8.8.7 =236 * **ENHANCEMENT:** Bulk Import overhaul. Imported IPs are now strictly categorized under a new `bulk_import` block type, fixing issues where imported blocks were permanently categorized as Manual blocks.237 * **ENHANCEMENT:** Streamlined the "Bulk Import" modal UI. Removed the redundant "Reason" field since all imports now securely force the "Bulk Import" reason programmatically to ensure filtering reliability.238 * **UX/SECURITY:** Changed the default duration in the Bulk Import block modal from "Permanent" to "24 Hours". This is in line with strict security industry standards, preventing unmanageable boundless table growth from unintended permanent bans.239 * **ROBUSTNESS:** Enhanced JavaScript handling in the Bulk Import modal to prevent caching issues from crashing the import button.240 241 = 8.8.6 =242 * **SECURITY ENHANCEMENT:** Upgraded the Threat Intelligence synchronization engine. Client scanning endpoints now enforce an authenticated V2 handshake to prevent unauthorized harvesting of the vulnerability database.243 * **OPTIMIZATION:** The AIB Community Network now fully offloads blocklist distribution to the Cloudflare Edge, dramatically improving sync speed and eliminating server load during large blocklist updates.244 245 = 8.8.5 =246 * **CRITICAL FIX (AJAX/Editor Conflict):** Resolved a severe conflict where the "Attack Signature Engine" was incorrectly intercepting background AJAX requests (like `admin-ajax.php`), causing infinite loading loops in page builders (Elementor) and our own Security Dashboard. Standard AJAX and REST API requests are now safely excluded.247 * **PERFORMANCE (Cloudflare Sync):** Implemented a "Memory Reconciliation" (Delta Sync) module for Cloudflare. The plugin now fetches active rules via a single API call and only pushes missing IPs (the delta) to Cloudflare, eliminating the `cURL error 28: Operation timed out` that occurred when syncing large databases on shared hosting.248 249 = 8.8.4 =250 * **CRITICAL FIX:** Resolved the "Spamhaus Drop List" automatic update failure. The cron job is now correctly registered and updating the list daily.251 * **FIX:** Fixed a UI issue where the "Bulk Import" form in the Whitelist section was displaying inline instead of in a modal.252 253 = 8.8.3 =254 * **NEW FEATURE:** "Impersonator Detection" (Fake Crawler Protection). Bots claiming to be Google/Bing are now verified via DNS. If they fail, they are flagged as "Impersonators" and blocked/logged.255 * **NEW FEATURE:** Bulk Import/Export for IP Lists! Easily manage large IP whitelists via CSV/Text.256 * **ENHANCEMENT:** Attack Signature Notifications. You can now configure the frequency (Instant, Daily, Weekly) and recipients for signature detection alerts.257 * **FIX:** Resolved a critical issue where "Signature Flagged" events were missing from the Security Log filters.258 * **FIX:** Fixed an incorrect log call in the login protection logic that caused PHP warnings.259 260 = 8.8.2 =261 * **NEW FEATURE:** Granular Site Scanner settings. You can now enable/disable specific checks (SSL, Updates, PHP, WP, Debug) to tailor the scanner to your environment.262 * **IMPROVEMENT:** The Site Scanner now respects user preferences and skips disabled checks in both manual and scheduled scans.263 * **IMPROVEMENT:** Refined logic to prevent "skipped" checks from triggering false positive email alerts.264 * **DEV:** Added `apply_filters('advaipbl_site_scanner_results')` for developer customization.265 266 267 = 8.8.1 =268 * **CRITICAL FIX:** Resolved a PHP Fatal Error in the AbuseIPDB module that occurred when the API rate limit was exceeded.269 * **COMPATIBILITY:** Fixed XML-RPC compatibility issues with external editors (like MarsEdit). Valid authenticated requests now correctly bypass 2FA and 404/403 Lockdown protections.270 * **FIX:** Added missing event logging for "Signatures Flagged" in the Security Log.271 * **I18N:** Added missing translator comments to signature flagging reason strings.272 273 = 8.8.0 =274 * **MAJOR REFACTOR:** Complete architectural modernization. The plugin core has been refactored into modular "Managers", significantly improving stability, maintainability, and code organization.275 * **PERFORMANCE:** JavaScript assets have been split into feature-specific modules (Admin, Rules, Logs), reducing the initial page load weight and improving admin panel responsiveness.276 * **IMPROVEMENT:** Centralized Cron Manager. Background tasks are now handled by a dedicated controller, ensuring reliable scheduling and clean uninstallation of all events.277 * **IMPROVEMENT:** Enhanced "Plan A" reliability for REST API protection. The User Enumeration blocking logic now respects both IP and User-Agent whitelists.278 * **STABILITY:** Fixed various legacy bugs and race conditions identified during the code audit.279 280 = 8.7.5 =281 * **CRITICAL FIX:** Improved database integrity checks. The update process now strictly verifies the existence of all critical tables (like Blocked IPs and Signatures) and re-creates them if missing. This resolves improper installation states where tables might be absent after a file-only update.282 * **FIX:** Resolved an "Invalid rule data received" error when creating Advanced Rules with regex patterns. The JSON handling logic now correctly preserves escaped characters (backslashes).283 * **FIX:** Addressed a false positive in the SSL DeepScan where cron/loopback requests could report SSL as critical. The scanner now verifies the site's configured URL protocol in addition to the current connection.284 285 = 8.7.4 =286 * **NEW FEATURE:** Threat Intelligence Services (AIB Community & AbuseIPDB) now support the "JavaScript Challenge" action in addition to instant blocking. This allows you to verify suspicious traffic without blocking it outright, saving server resources.287 * **NEW FEATURE:** Internal Security & Forensics (Audit Logs) now support Push Notifications (Webhooks). Get instant alerts on Slack/Discord when critical audit events occur.288 * **FIX:** Resolved a synchronization issue in the "Block Duration" logic. The Blocked IPs table, Security Logs, and Notifications now consistently display the correct duration (e.g., 1440 mins) instead of defaulting to "Permanent" or showing discrepancies for Impersonation blocks.289 * **FIX:** Fixed the "Bot Impersonation" logic to correctly register the configured "Threat Score" points (e.g., 100/100) in the IP Trust Log before executing the immediate block.290 * **FIX:** Improved Unblock logic. Manually unblocking an IP (or using "Unblock All") now automatically removes it from the "Pending Reports" queue, preventing false positives from being sent to the Community Network.291 * **Code Quality:** Addressed various PHPCS warnings, including a security improvement in output escaping logic.292 293 = 8.7.3 =294 * **FEATURE:** Added search functionality to the "Blocked IPs" list, allowing admins to quickly find specific IPs or ranges.295 * **FIX:** Resolved "Table doesn't exist" error in the Audit Log when the feature is inactive.296 * **FIX:** Corrected "Array to string conversion" warning in Community Blocklist updates due to complex whitelist formats.297 * **IMPROVEMENT:** Enhanced robustness of IP whitelisting logic during community feed synchronization.298 299 = 8.7.2 =300 * **Fix (PHP 8.1+ Compatibility):** Resolved a deprecated warning ("passing null to parameter") in WordPress core. Updated the internal `status_header` hook usage to strict compliance.301 * **Fix:** Resolved a PHP warning ("Undefined variable $type") that occurred when removing IPs from the whitelist via the admin interface.302 * **Performance:** Optimized the Blocklist Generator. It now uses a "Fast Mode" to skip expensive DNS lookups during bulk generation, fixing execution timeouts on large lists.303 * **Improvement:** Migrated the Cloudflare "Clear All Rules" operation to a background asynchronous task, preventing UI freezes.304 305 = 8.7.1 =306 * **Performance:** Migrated the Cloudflare "Clear All" operation to a background process (Async). This ensures instant UI feedback and prevents PHP timeouts when clearing thousands of rules.307 * **Critical Fix (Priority):** Resolved a logic error where the AbuseIPDB check (Priority 10) was ignoring Global URI Exclusions. Excluded URLs are now correctly bypassed before any API calls.308 * **Fix:** The "Unblock All" button now correctly removes all plugin-managed rules (`[AIB]` tagged) from Cloudflare, fixing potential "phantom blocks" synchronization issues.309 * **Maintenance:** Improved plugin deactivation/uninstall routines to ensure all scheduled background tasks are properly cleaned up.310 311 = 8.7 =312 * **NEW MAJOR FEATURE: Internal Security & Forensics Suite.** A comprehensive auditing system that tracks user activity (Audit Log) and monitors file system integrity (FIM) to detect breaches or unauthorized changes.313 * **NEW FEATURE: Activity Audit Log.** Records critical events like plugin changes, setting updates, and login activity. Includes a searchable UI and automated log rotation.314 * **NEW FEATURE: File Integrity Monitor (FIM).** Automatically scans critical core and plugin files for unauthorized modifications. Alerts you instantly via email if a file hash changes.315 * **NEW FEATURE: Deep Scan Email Reports.** Enhanced weekly security report now includes "Pending Updates" status and a summary of known vulnerabilities, keeping you informed without logging in.316 * **Enhancement:** Added "Downloads History" to the Telemetry Dashboard card.317 * **Enhancement:** Improved "Clear Audit Logs" reliability with AJAX handling.318 * **Security Fix:** Fixed CSP header to correctly allow Stripe/Sift scripts only on the "About" page.319 * **Fix:** Resolved a race condition in AbuseIPDB checks that could cause duplicate email notifications.320 * **Fix:** Addressed various PHPCS and linting warnings for cleaner code.321 322 = 8.6.11 =323 * **Critical Fix (ASN Whitelisting):** Corrected a validation issue where ASN Whitelist entries with comments (e.g., "AS32934 # Facebook") were failing the strict check. The logic now properly sanitizes the whitelist before validation.324 * **Critical Fix (IPv6):** Fixed CIDR validation logic to correctly support 128-bit IPv6 ranges. Previously, it was incorrectly restricted to 32 bits, causing valid IPv6 ranges to be rejected.325 * **Improvement (Geolocation):** Implemented a robust fallback mechanism. If the Local MaxMind Database lookup fails (or finds no data), the system now seamlessly attempts to fetch the data via the real-time API, ensuring critical ASN/Country checks don't fail silently.326 327 = 8.6.10 =328 * **NEW FEATURE: Enhanced Lockdown Forensics.** Added detailed sampling for Distributed Lockdown events (404/403). Administrators can now see the exact URIs, timestamps, and user-agents of the requests that triggered a lockdown in the details popup.329 * **Fix:** Resolved a PHP warning (`undefined variable $block_reason_code`) in the `monitor_threat_score` function, ensuring cleaner error logs.330 331 = 8.6.9 =332 * **NEW FEATURE: Username Blocking.** Added "Username" as a new condition type for Advanced Rules. You can now create rules to Block, Challenge, or Score login attempts based on specific usernames (e.g., block "admin" or "test").333 * **Enhanced Notifications:** Enabled Email and Push notifications for Distributed Lockdowns (404/403 errors), ensuring administrators are alerted when these automated defenses kick in.334 * **Security Fix (Compliance):** Added strict direct file access protection to `advaipbl-loader.php`. Implemented a smart check to satisfy security scanners (Plugin Check) while maintaining Edge Mode compatibility.335 * **Improvement (Logging):** Added "Endpoint Challenge" event logging. Challenges served by the 404/403 Lockdown system are now properly recorded in the Security Log for auditing.336 * **Improvement (Smarter Scanning):** Enhanced theme detection logic in the Site Scanner to better identify active themes even when standard WordPress functions return incomplete data.337 * **Improvement (Onboarding):** New installations now come with a default whitelist of safe ASNs (Cloudflare, Google, etc.) to prevent accidental blocking of critical infrastructure.338 339 = 8.6.8 =340 * **NEW MAJOR FEATURE: Admin Bar Menu.** Added a comprehensive "Security" menu to the WordPress Admin Bar. Administrators can now quickly access settings, flush caches, view logs, and toggle "Panic Mode" from any page.341 * **NEW FEATURE: Distributed Lockdown (403/404).** Introduced a smart defense mechanism that automatically locks down the site for an IP subnet or country if they trigger excessive 404 or 403 errors, protecting against distributed brute-force and resource probing.342 * **Critical Fix (ASN Whitelisting):** Resolved a logic conflict that prevented API-based geolocation users from successfully whitelisting critical services like Stripe or Google via their ASN.343 * **Bugfix:** Fixed a JavaScript error ("cannot read properties of undefined") on the Post Editor screen that could interrupt the "Add Tag" functionality.344 * **Telemetry:** Enhanced telemetry to track the usage of the new Distributed Lockdown features.345 346 = 8.6.7 =347 * **NEW MAJOR FEATURE: HTTP Security Headers.** Added a comprehensive manager to easily configure and enforce security headers (HSTS, X-Frame-Options, CSP, etc.) directly from the dashboard. This improves your site's security grade and protects users from browser-based attacks.348 * **Enhancement:** Integrated the "Security Headers" menu into the Admin Bar for quick access.349 * **Critical Fix (Advanced Rules):** Refined the "Allow" rule logic. Global Allow rules now correctly bypass subsequent IP checks (like AbuseIPDB), ensuring that whitelisted traffic is never blocked by external threat intelligence.350 * **UX:** Added a direct help link to the Security Headers page.351 352 = 8.6.6 =353 * **Critical Security Fix (Zero-Tolerance):** "Impersonation" events are now blocked instantly, bypassing the Threat Scoring system. This ensures that any bot pretending to be Google/Bing but failing DNS verification is stopped immediately, regardless of score settings.354 * **Logic Refinement (The "Equilibrium" Fix):** Reordered the security check priority. The "Allow" Advanced Rules and IP Whitelists are now evaluated *before* the global blocklists (like Community Network). This allows administrators to create effective "bypass rules" for IPs that might be listed in global blacklists.355 * **Documentation:** Added verified credits for AbuseIPDB and Wordfence Intelligence. Added context-aware help links for reCAPTCHA settings.356 * **Code Quality:** Addressed strict PHPCS warnings (SQL preparation, Nonce verification, Output escaping) across the codebase for improved security and stability.357 358 = 8.6.5 =359 * **Improvement: Enhanced the "Known Bot Verification" engine. Refined DNS validation logic to better handle specific SEO crawlers (like Ahrefs, MJ12bot) and IPv6 configurations, preventing false "Impersonation" blocks.360 * **Fix: Resolved a DNS resolution edge case where hostnames with trailing dots could cause validation failures on some server environments.361 * **Tweak: Updated the default list of User-Agents and WAF rules to include protection against modern scraper libraries (Scrapy, Go-http-client).362 363 = 8.6.4 =364 * **Critical Fix (Performance): Resolved a bug where the "Community List Update" cron job could be scheduled multiple times, causing excessive background tasks. This update automatically cleans up duplicate events.365 * **NEW FEATURE: Server Reputation Scanner. Added a tool in the "Site Scanner" tab to check if your server's IP address is blacklisted by Spamhaus or AbuseIPDB, helping you identify hosting-related issues.366 * **Improvement: Optimized the cron scheduling logic to prevent future duplication of tasks.367 * **Improvement: Enhanced the Site Scanner UI with clearer status indicators and action buttons.368 369 370 = 8.6.3 =371 * **NEW MAJOR FEATURE: Site Health & Vulnerability Scanner. Added a comprehensive security audit tool. It checks for critical issues like outdated PHP, debug mode risks, and scans your plugins/themes against a database of 30,000+ known vulnerabilities.372 * **Architecture Upgrade: Migrated the "Community Defense Network" IP list to a dedicated custom database table for extreme performance and scalability. This eliminates memory overhead even with thousands of blocked IPs.373 * **Compatibility: Verified full compatibility with WordPress 6.9.374 * **UI Enhancement: Added help icons and direct documentation links to advanced settings for easier configuration.375 * **Improvement: The setup wizard now automatically enables the Server-Level Firewall (.htaccess) for stronger default protection.376 377 = 8.6.2 =378 * **NEW MAJOR FEATURE: Community Defense Network (Beta). Launched our collaborative threat intelligence network. You can now opt-in to share anonymized attack reports and protect your site with a global blocklist generated from verified community data.379 * **Enhancement: Increased default block duration to 24 hours (1440 mins) for stronger protection and better data quality for the community network.380 * **Performance: Optimized the wp_options storage for the community blocklist to prevent autoloading, ensuring zero impact on site load time.381 * **Security Hardening: Updated default WAF rules to include protection against Scrapy, Go-http-client, and common log/backup file scanners (.sql, .log).382 * **Improvement: The "Clean Expired IPs" cron job now automatically syncs removals with Cloudflare and Htaccess, ensuring that temporary bans are lifted correctly across all firewalls.383 * **Fix: Resolved a display issue where the "Settings" tab content could be malformed if certain options were disabled.384 385 = 8.6.1 =386 * **NEW MAJOR FEATURE: Cloud Edge Defense. Introducing cloud-based blocking. Integrate seamlessly with Cloudflare to sync your "Manually Blocked" and "Permanent" IPs directly to the Cloudflare Firewall (WAF). This stops attackers at the network edge, reducing server load to zero.387 * **NEW MAJOR FEATURE: Server-Level Firewall. Added a high-performance module that writes blocking rules and file hardening directives (wp-config.php, .git, etc.) directly to your .htaccess file. Includes automatic backups and dual-stack Apache support.388 * **Critical Fix: Resolved a false positive issue affecting legitimate iOS users (iCloud Private Relay) and social media link previews, which were incorrectly flagged as "Bot Impersonators".389 * **Enhancement: Completely redesigned the Settings experience with a new "Help Center" approach, providing direct links to documentation for complex features.390 * **Enhancement: Updated the Setup Wizard to include Server-Level Firewall activation and better guidance for advanced integrations.391 * **Performance: Optimized the IP blocking logic to handle bulk actions efficiently by updating external firewalls (Htaccess/Cloudflare) only once per batch.392 * **Telemetría: Updated data points to track adoption of Cloudflare and Htaccess features.393 394 = 8.6.0 =395 * **NEW MAJOR FEATURE: Server-Level Firewall (.htaccess).** Introducing the ultimate performance upgrade. You can now write blocking rules directly to your server's `.htaccess` file. This blocks threats before WordPress loads, saving massive server resources. Includes automatic backups, proxy awareness (`SetEnvIF`), and support for Apache 2.2/2.4.396 * **Feature: File Hardening.** Easily block access to sensitive system files (`wp-config.php`, `readme.html`, etc.) at the server level.397 * **Feature: Auto-Synchronization.** Automatically syncs your "Manually Blocked" and "Permanent" IPs from the database to the server firewall.398 * **Feature: Temporary Block Offloading.** Optionally push temporary blocks (like 404 abusers or failed logins) to the server firewall for the duration of their ban.399 * **Critical Fix: Bot Verification.** Resolved a false positive issue where legitimate iOS users (using iCloud Private Relay) or social media app browsers (Instagram/Facebook in-app) were being blocked as "Bot Impersonators". The verification logic has been refined to exclude social bots from strict DNS checks while maintaining security for search engine crawlers.400 * **Enhancement:** Updated Telemetry receiver to track the adoption of the new firewall features.401 * **UI/UX:** Integrated the new firewall controls into the main Settings tab for a streamlined experience.402 403 404 405 241 == Upgrade Notice == 406 242 407 = 8.8.9 = 408 **SECURITY UPDATE:** Patches a vulnerability in the Settings exporter where the "Template (No API Keys)" file was accidentally leaking Cloudflare and AbuseIPDB API keys. Update immediately if you plan to export your configuration templates to share with others. 409 410 = 8.8.8 = 411 **CRITICAL UPDATE:** Fixes a `.htaccess` synchronization bug with the Bulk Import tool. Resolves a regression where Bulk Imports stopped pushing new blocks to Cloudflare. Update immediately to ensure imported IPs are actively blocking threats at both the server level and the cloud edge. 412 413 = 8.8.7 = 414 **FEATURE & UX UPDATE:** Overhauled the Bulk Import Blocked IPs functionality. Includes a new `bulk_import` filtering type and smarter, safer defaults (24 hours instead of Permanent). 415 416 = 8.8.6 = 417 **SECURITY UPDATE:** Introduces V2 authenticated synchronization for threat intelligence endpoints and shifts blocklist distribution to Cloudflare Edge. Recommended update for all users. 418 419 = 8.8.5 = 420 **CRITICAL UPDATE:** Fixes infinite loading conflicts with Elementor and background AJAX requests. Also resolves Cloudflare synchronization timeouts. Update immediately. 421 422 = 8.8.4 = 423 **CRITICAL UPDATE:** Fixes automatic Spamhaus updates and Bulk Import display issues. Update immediately. 424 425 = 8.8.3 = 426 **NEW FEATURES:** Impersonator Detection & Bulk Whitelist Import! Also fixes a critical issue with Security Log visibility and improves notification logic. 427 = 8.8.2 = 428 **FEATURE UPDATE:** Granular Site Scanner controls! You can now selectively enable/disable specific security checks (SSL, Updates, etc.) to prevent false positives. 243 = 8.9.0 = 244 **MAJOR UPDATE:** This release launches the AIB Cloud Network V3 and the powerful "Whitelist Login Countries" feature. Update immediately to connect to the new, more secure threat intelligence network infrastructure and take absolute control over your login page access. -
advanced-ip-blocker/trunk/uninstall.php
r3476940 r3481949 26 26 27 27 if ( ! empty( $settings_option['delete_data_on_uninstall'] ) && '1' === $settings_option['delete_data_on_uninstall'] ) { 28 29 // --- 0. UNREGISTER FROM CENTRAL SERVER --- 30 // Must be done before options are deleted from the database 31 $api_token = $settings_option['api_token_v3'] ?? ''; 32 if (!empty($api_token)) { 33 wp_remote_post('https://advaipbl.com/wp-json/aib-api/v3/unregister', [ 34 'headers' => [ 35 'Authorization' => 'Bearer ' . $api_token, 36 'Content-Type' => 'application/json', 37 'Accept' => 'application/json' 38 ], 39 'timeout' => 10, 40 'blocking' => false // No need to wait for response during uninstall 41 ]); 42 } 28 43 29 44 global $wpdb; … … 179 194 } 180 195 181 // --- 3. Borrar Transients ---196 // --- 4. Borrar Transients --- 182 197 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 183 198 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE %s OR `option_name` LIKE %s", $wpdb->esc_like( '_transient_advaipbl_' ) . '%', $wpdb->esc_like( '_transient_timeout_advaipbl_' ) . '%' ) ); 184 199 185 // --- 4. Borrar Metadatos de Usuario de 2FA ---200 // --- 5. Borrar Metadatos de Usuario de 2FA --- 186 201 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 187 202 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->usermeta} WHERE `meta_key` LIKE %s", $wpdb->esc_like( '_advaipbl_2fa_' ) . '%' ) );
Note: See TracChangeset
for help on using the changeset viewer.