Changeset 3764759
- Timestamp:
- 10/25/2026 02:34:20 PM (73 minutes ago)
- Location:
- cyberpulse/trunk
- Files:
-
- 16 edited
-
assets/js/cyberpulse-403.js (modified) (5 diffs)
-
cyberpulse-core.php (modified) (16 diffs)
-
cyberpulse-htaccess.php (modified) (24 diffs)
-
cyberpulse-tabs.php (modified) (4 diffs)
-
cyberpulse.php (modified) (1 diff)
-
languages/cyberpulse-de_DE.php (modified) (2 diffs)
-
languages/cyberpulse-en_US.php (modified) (2 diffs)
-
languages/cyberpulse-es_ES.php (modified) (2 diffs)
-
languages/cyberpulse-fr_FR.php (modified) (2 diffs)
-
languages/cyberpulse-it_IT.php (modified) (2 diffs)
-
languages/cyberpulse-ja.php (modified) (2 diffs)
-
languages/cyberpulse-ko_KR.php (modified) (2 diffs)
-
languages/cyberpulse-pt_BR.php (modified) (2 diffs)
-
languages/cyberpulse-ru_RU.php (modified) (2 diffs)
-
languages/cyberpulse-zh_CN.php (modified) (2 diffs)
-
readme.txt (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
cyberpulse/trunk/assets/js/cyberpulse-403.js
r3757045 r3764759 2 2 * CyberPulse — 403 block page script. 3 3 * 4 * Handles the human-verification form on the block page: submits the5 * math answer together with the signed token, and reacts to success,6 * server-side failure, and network failure.4 * Handles both: 5 * 1. Static Apache page (localization only). 6 * 2. Dynamic PHP page (human-verification form). 7 7 * 8 8 * @package CyberPulse … … 11 11 'use strict'; 12 12 13 // ==================== HUMAN VERIFICATION ==================== 13 // ==================== STATIC PAGE LOCALIZATION ==================== 14 // This runs ONLY on the static cyberpulse-403.html page. 15 (function initStaticLocalization() { 16 var titleEl = document.getElementById("cp-403-title"); 17 if (!titleEl) return; // Not on the static page, exit. 14 18 15 /** 16 * Validates the answer locally (non-empty only) and submits it to 17 * the cybersec_human_verify AJAX endpoint. 18 * 19 * The actual math check is intentionally NOT performed client-side — 20 * the server compares the submitted value against the expected 21 * answer stored in a transient. This prevents an attacker from 22 * reading the correct value out of the page source. 23 * 24 * UI states: 25 * - success: shows a checkmark, redirects after 1.5s 26 * - bad answer / server error: shows the returned message and 27 * a refresh link, re-enables the form, clears the input 28 * - network error: shows the connection error and a refresh link, 29 * re-enables the form 30 */ 19 var lang = (navigator.language || navigator.userLanguage || 'en').slice(0, 2).toLowerCase(); 20 21 var translations = { 22 "ru": { title: "Доступ запрещен", desc: "Ваш запрос был заблокирован системой безопасности сервера.", btn: "Обновить страницу" }, 23 "de": { title: "Zugriff verweigert", desc: "Ihre Anfrage wurde vom Sicherheitssystem des Servers blockiert.", btn: "Seite neu laden" }, 24 "fr": { title: "Accès refusé", desc: "Votre demande a été bloquée par le système de sécurité du serveur.", btn: "Actualiser la page" }, 25 "es": { title: "Acceso denegado", desc: "Su solicitud fue bloqueada por el sistema de seguridad del servidor.", btn: "Actualizar página" }, 26 "it": { title: "Accesso negato", desc: "La tua richiesta è stata bloccata dal sistema di sicurezza del server.", btn: "Aggiorna pagina" }, 27 "pt": { title: "Acesso negado", desc: "Sua solicitação foi bloqueada pelo sistema de segurança do servidor.", btn: "Atualizar página" }, 28 "zh": { title: "拒绝访问", desc: "您的请求已被服务器安全系统拦截。", btn: "刷新页面" }, 29 "ja": { title: "アクセス拒否", desc: "リクエストはサーバーのセキュリティシステムによってブロックされました。", btn: "ページを更新" }, 30 "ko": { title: "액세스 거부됨", desc: "귀하의 요청이 서버 보안 시스템에 의해 차단되었습니다.", btn: "페이지 새로고침" } 31 }; 32 33 if (translations[lang]) { 34 var descEl = document.getElementById("cp-403-desc"); 35 var btnEl = document.getElementById("cp-403-btn"); 36 37 titleEl.innerText = "403 " + translations[lang].title; 38 if (descEl) descEl.innerText = translations[lang].desc; 39 if (btnEl) btnEl.innerText = translations[lang].btn; 40 } 41 })(); 42 43 // ==================== DYNAMIC PAGE HUMAN VERIFICATION ==================== 44 // This runs ONLY on the PHP-generated page where cybersec403Data exists. 31 45 function verifyHuman() { 46 // Safety check: if PHP data is missing, do nothing. 47 if (typeof cybersec403Data === 'undefined') return; 48 32 49 var answerInput = document.getElementById('sw-human-answer'); 33 50 var errorDiv = document.getElementById('sw-test-error'); … … 38 55 } 39 56 40 var answer = answerInput.value;57 var answer = answerInput.value; 41 58 42 59 if (!answer) { … … 46 63 } 47 64 48 // Client-side math check removed — server validates the answer49 // against the transient-stored expected value.50 65 errorDiv.style.display = 'none'; 51 66 verifyBtn.disabled = true; … … 92 107 } 93 108 94 // ==================== INITIALIZATION ==================== 95 96 /** 97 * Wires up the verification form once the DOM is ready: 98 * Enter-to-submit, click-to-submit, and auto-focus on the input. 99 */ 109 // ==================== DYNAMIC PAGE INITIALIZATION ==================== 100 110 document.addEventListener('DOMContentLoaded', function() { 101 111 var answerInput = document.getElementById('sw-human-answer'); 102 112 var verifyBtn = document.getElementById('sw-verify-btn'); 103 113 104 if (answerInput) { 105 answerInput.addEventListener('keypress', function(e) { 106 if (e.key === 'Enter') { 107 verifyHuman(); 108 } 109 }); 110 } 114 // If these elements don't exist, we are on the static page. Skip. 115 if (!answerInput || !verifyBtn) return; 111 116 112 if (verifyBtn) { 113 verifyBtn.addEventListener('click', verifyHuman); 114 } 117 answerInput.addEventListener('keypress', function(e) { 118 if (e.key === 'Enter') { 119 verifyHuman(); 120 } 121 }); 115 122 116 // Auto-focus the input field 117 if (answerInput) { 118 setTimeout(function() { 119 answerInput.focus(); 120 }, 100); 121 } 123 verifyBtn.addEventListener('click', verifyHuman); 124 125 setTimeout(function() { 126 answerInput.focus(); 127 }, 100); 122 128 }); 123 129 -
cyberpulse/trunk/cyberpulse-core.php
r3763154 r3764759 45 45 define('CYBERSEC_PERMANENT_BLOCKED_SUBNETS', 'secwall_permanent_blocked_subnets'); 46 46 define('CYBERSEC_UA_BLOCKS_OPTION', 'secwall_blocked_user_agents'); 47 define('CYBERSEC_VERSION', '5.9.1. 2');47 define('CYBERSEC_VERSION', '5.9.1.3'); 48 48 49 49 if (!file_exists(CYBERSEC_LOG_DIR)) { … … 99 99 'force_secure_cookies' => 1, 100 100 'rate_limiting_enabled' => 1, 101 'rate_limit_requests' => 60,101 'rate_limit_requests' => 40, 102 102 'rate_limit_window' => 60, 103 103 'rest_api_protection' => 1, … … 116 116 'ai_training_block_enabled' => 1, 117 117 'ai_search_block_enabled' => 0, 118 'force_https' => 0, 118 119 ); 119 120 … … 2723 2724 } 2724 2725 2726 // Chrome < 90. 2727 // Exceptions: real browsers (Yandex, Opera, Edge, etc.) that also carry Chrome/<ver> token. 2728 if ($chrome_ver > 0 && $chrome_ver < 90) { 2729 $real_old_browsers = array('YaBrowser', 'OPR/', 'Edg/', 'SamsungBrowser', 'Brave', 'Vivaldi', 'CriOS', 'FxiOS', 'OPiOS'); 2730 $is_real = false; 2731 foreach ($real_old_browsers as $b) { 2732 if (stripos($ua, $b) !== false) { $is_real = true; break; } 2733 } 2734 // Do not block if it's a real browser or actual old mobile device 2735 if (!$is_real && stripos($ua, 'Mobile') === false && stripos($ua, 'Android') === false) { 2736 return true; 2737 } 2738 } 2739 2725 2740 if ($chrome_ver > 0 && stripos($ua, 'Macintosh') !== false) { 2726 if ($chrome_ver >= 762727 && (empty($_SERVER['HTTP_SEC_FETCH_SITE']) || empty($_SERVER['HTTP_SEC_FETCH_MODE']))) {2728 return true;2729 }2730 if ($chrome_ver >= 76 && !cybersec_looks_like_real_chrome()) {2731 return true;2732 }2733 }2741 if ($chrome_ver >= 76 2742 && (empty($_SERVER['HTTP_SEC_FETCH_SITE']) || empty($_SERVER['HTTP_SEC_FETCH_MODE']))) { 2743 return true; 2744 } 2745 if ($chrome_ver >= 76 && !cybersec_looks_like_real_chrome()) { 2746 return true; 2747 } 2748 } 2734 2749 2735 2750 if ($chrome_ver >= 76 … … 2737 2752 && stripos($ua, 'Android') === false 2738 2753 && !cybersec_looks_like_real_chrome()) { 2739 return true;2740 }2754 return true; 2755 } 2741 2756 2742 2757 // Internal consistency … … 2755 2770 if (stripos($ua, 'Edg/') !== false) return true; 2756 2771 } 2772 2773 // Firefox < 90. 2774 if ($ff_ver < 90) { 2775 $real_ff = array('Waterfox', 'PaleMoon', 'SeaMonkey', 'Iceweasel'); 2776 $is_real_ff = false; 2777 foreach ($real_ff as $r) { 2778 if (stripos($ua, $r) !== false) { $is_real_ff = true; break; } 2779 } 2780 // Exclude actual old mobile devices 2781 if (!$is_real_ff && !$is_fxios && stripos($ua, 'Mobile') === false && stripos($ua, 'Android') === false) { 2782 return true; 2783 } 2784 } 2757 2785 } 2758 2786 … … 2765 2793 $ver = (int)$vm[1]; 2766 2794 if ($ver > 100) { 2795 return true; 2796 } 2797 2798 // Safari Version < 14 = bot. 2799 // Exclude mobile devices (old iPhones/iPads cannot update). 2800 if ($ver < 14 && stripos($ua, 'Mobile') === false && stripos($ua, 'iPad') === false) { 2767 2801 return true; 2768 2802 } … … 2799 2833 } 2800 2834 2801 // Known botnet fingerprints — exact old Chrome builds2835 // Known botnet fingerprints — exact old Chrome builds 2802 2836 // (identical UA from multiple countries within minutes = scraper farm) 2803 2837 $botnet_fingerprints = array( … … 2822 2856 } 2823 2857 2824 // v5.9.0.10: Opera Presto (defunct since 2013) — any "Presto/" marker is a bot2858 // Opera Presto 2825 2859 if (stripos($ua, 'Presto/') !== false) { 2826 2860 return true; 2827 2861 } 2828 2862 2829 // v5.9.0.10: Windows CE — EOL since 2013, no real users exist2863 // Windows CE 2830 2864 if (stripos($ua, 'Windows CE') !== false) { 2831 2865 return true; … … 2843 2877 2844 2878 if (preg_match('/Windows NT (6\.1|6\.3)/', $ua) 2845 && $chrome_ver > 02846 && $chrome_ver < 1102847 && !cybersec_looks_like_real_chrome()) {2848 return true;2849 }2879 && $chrome_ver > 0 2880 && $chrome_ver < 110 2881 && !cybersec_looks_like_real_chrome()) { 2882 return true; 2883 } 2850 2884 2851 2885 // AI bots — block before any whitelist … … 2907 2941 // Tool & script detection 2908 2942 $tool_patterns = array( 2909 'libwww-perl','curl/','wget/','Go-http-client','Java/',2910 'Apache-HttpClient','zgrab','masscan','nmap','sqlmap','nikto','nessus',2911 'HeadlessChrome','PhantomJS','Selenium','puppeteer',2912 'keys-so-bot','SERankingBacklinksBot','scrapy',2913 'BacklinksExtendedBot','AffsignalCrawler','SeopultContentAnalyzer','Photon/',2914 'python-requests','python-urllib','python-httpx',2915 'node-fetch','axios/','okhttp/',2916 'Faraday/','Rest-Client','Typhoeus','Excon/',2917 );2943 'libwww-perl','curl/','wget/','Go-http-client','Java/', 2944 'Apache-HttpClient','zgrab','masscan','nmap','sqlmap','nikto','nessus', 2945 'HeadlessChrome','PhantomJS','Selenium','puppeteer', 2946 'keys-so-bot','SERankingBacklinksBot','scrapy', 2947 'BacklinksExtendedBot','AffsignalCrawler','SeopultContentAnalyzer','Photon/', 2948 'python-requests','python-urllib','python-httpx', 2949 'node-fetch','axios/','okhttp/', 2950 'Faraday/','Rest-Client','Typhoeus','Excon/', 2951 ); 2918 2952 foreach ($tool_patterns as $tool) { 2919 2953 if (stripos($ua, $tool) !== false) return true; … … 2952 2986 if (preg_match('/(Windows NT|Macintosh|X11; Linux|x86_64|Intel Mac OS X)/', $ua)) return false; 2953 2987 return true; 2954 }2955 }2956 2957 // Old Firefox (except known forks)2958 if (preg_match('/Firefox\/(\d+)\./', $ua, $m)) {2959 $fv = (int)$m[1];2960 if ($fv < 60) {2961 $real_ff = array('Waterfox', 'PaleMoon', 'SeaMonkey', 'Iceweasel');2962 $is_real = false;2963 foreach ($real_ff as $r) {2964 if (stripos($ua, $r) !== false) { $is_real = true; break; }2965 }2966 if (!$is_real) return true;2967 2988 } 2968 2989 } … … 4660 4681 if(is_admin()||wp_doing_ajax()||wp_doing_cron()) return; 4661 4682 if(defined('REST_REQUEST')&&REST_REQUEST) return; 4683 4684 $early_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; 4685 4686 if (preg_match('#^/(ads\.txt|app-ads\.txt|robots\.txt|favicon\.ico|sellers\.json|security\.txt)(\?|$)#i', $early_uri)) { 4687 return; 4688 } 4689 4690 if (strpos($early_uri, '/.well-known/') === 0) { 4691 return; 4692 } 4662 4693 4663 4694 $early_ip = cybersec_get_visitor_ip(); … … 4878 4909 if (preg_match($bad_re, $ua_check)) { 4879 4910 cybersec_increment_stat('blocked'); 4880 cybersec_ban_and_log($ip_early, 'Static file via bot UA: ' . $bad_re, true);4911 cybersec_ban_and_log($ip_early, cybersec_translate('Static file via bot UA') . ': ' . $bad_re, true); 4881 4912 cybersec_show_block_page($ip_early, cybersec_translate('Access denied.')); 4882 4913 exit; … … 6685 6716 add_action('init', 'cybersec_force_secure_cookies', 1); 6686 6717 6718 // ==================== FORCE HTTPS REDIRECT ==================== 6719 6720 /** 6721 * Redirects non-HTTPS requests to HTTPS with a 301. 6722 * 6723 * Trusts X-Forwarded-Proto: https so the redirect does not loop when 6724 * the site sits behind a TLS-terminating reverse proxy — is_ssl() 6725 * returns false in that case even though the client connected over 6726 * HTTPS. Fires on init priority 1, after brute-force check (0) and 6727 * alongside other early security hooks. 6728 * 6729 * Disabled by default. Enable only after confirming the SSL cert 6730 * covers the site's canonical domain (and www. alias, if used). 6731 */ 6732 function cybersec_force_https() { 6733 $s = cybersec_get_settings(); 6734 if (empty($s['force_https'])) return; 6735 if (is_ssl()) return; 6736 if (wp_doing_ajax() || wp_doing_cron() || (defined('WP_CLI') && WP_CLI)) return; 6737 if (defined('REST_REQUEST') && REST_REQUEST) return; 6738 6739 $fwd_proto = isset($_SERVER['HTTP_X_FORWARDED_PROTO']) 6740 ? strtolower(sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_PROTO']))) 6741 : ''; 6742 if ($fwd_proto === 'https') return; 6743 6744 $host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; 6745 $uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; 6746 if (empty($host)) return; 6747 6748 wp_safe_redirect('https://' . $host . $uri, 301); 6749 exit; 6750 } 6751 add_action('init', 'cybersec_force_https', 1); 6752 6687 6753 /** 6688 6754 * Global rate limiter. Tracks requests per IP in the configured window … … 7152 7218 if(get_option(CYBERSEC_PAGES_OPTION)===false) update_option(CYBERSEC_PAGES_OPTION,array(home_url())); 7153 7219 if(get_option(CYBERSEC_BOT_OPTIONS)===false) update_option(CYBERSEC_BOT_OPTIONS,cybersec_get_default_bot_options()); 7154 if(get_option(CYBERSEC_SETTINGS_OPTION)===false) { $default_settings = cybersec_get_settings(); $recommended = array('auto_unblock_minutes'=>30,'alert_threshold'=>20,'alert_minutes'=>5,'brute_max_attempts'=>5,'brute_window_minutes'=>15,'rate_limit_requests'=> 60,'rate_limit_window'=>60,'max_revisions'=>5,'auto_clean_logs_days'=>30,'referer_history_threshold'=>1,'referer_rate_1min'=>5,'referer_rate_5min'=>10,'referer_same_page'=>3,'referer_no_proxy_rate'=>3); $default_settings = array_merge($default_settings, $recommended); update_option(CYBERSEC_SETTINGS_OPTION, $default_settings); }7220 if(get_option(CYBERSEC_SETTINGS_OPTION)===false) { $default_settings = cybersec_get_settings(); $recommended = array('auto_unblock_minutes'=>30,'alert_threshold'=>20,'alert_minutes'=>5,'brute_max_attempts'=>5,'brute_window_minutes'=>15,'rate_limit_requests'=>40,'rate_limit_window'=>60,'max_revisions'=>5,'auto_clean_logs_days'=>30,'referer_history_threshold'=>1,'referer_rate_1min'=>5,'referer_rate_5min'=>10,'referer_same_page'=>3,'referer_no_proxy_rate'=>3); $default_settings = array_merge($default_settings, $recommended); update_option(CYBERSEC_SETTINGS_OPTION, $default_settings); } 7155 7221 if(get_option(CYBERSEC_WHITELIST_OPTION)===false) update_option(CYBERSEC_WHITELIST_OPTION,array()); 7156 7222 if(get_option(CYBERSEC_TEMP_BLOCKS_OPTION)===false) update_option(CYBERSEC_TEMP_BLOCKS_OPTION,array()); -
cyberpulse/trunk/cyberpulse-htaccess.php
r3763154 r3764759 1 1 <?php 2 /**3 * CyberPulse — .htaccess management for Apache / LiteSpeed.4 *5 * Requests to existing files (.git/objects/*, wp-config.php.bak,6 * /.aws/credentials, /backup.sql) never reach PHP: Apache serves them7 * as static content because WordPress's own rewrite rule uses8 * `RewriteCond !-f` ("if file exists, don't pass to index.php").9 * Only the web server can block these requests, so the rules must10 * live in .htaccess BEFORE the WordPress block.11 *12 * The plugin owns only its own marker-delimited section:13 *14 * # BEGIN CyberPulse Protection15 * ...16 * # END CyberPulse Protection17 *18 * On deactivation the block is removed and the rest of .htaccess19 * (WP Fastest Cache, Wordfence, etc.) is left untouched.20 *21 * OPT-IN: this protection is disabled by default. Rules are written22 * only when the admin explicitly enables "htaccess_protection_enabled"23 * in plugin settings. This prevents accidental breakage of SEO tools,24 * nginx setups, or custom server configs on fresh installs.25 *26 * @package CyberPulse27 */28 29 2 if (!defined('ABSPATH')) exit; 30 3 … … 37 10 38 11 /** 39 * Returns true if the current web server reads .htaccess files. 40 * Apache and LiteSpeed do; nginx does not. 41 * 42 * @return bool 12 * Checks whether the current web server honors .htaccess files. 13 * 14 * Apache and LiteSpeed read .htaccess natively; nginx does not. 15 * When SERVER_SOFTWARE is unavailable (CLI, some FPM setups), the 16 * function assumes .htaccess works — the caller is expected to 17 * handle any resulting error gracefully via the verification step 18 * in cybersec_htaccess_sync(). 19 * 20 * @return bool True when .htaccess rules will actually take effect. 43 21 */ 44 22 function cybersec_htaccess_server_supports() { … … 48 26 49 27 if ($server === '') { 50 // CLI / cron — assume Apache51 28 return !defined('WP_CLI') || !WP_CLI; 52 29 } … … 57 34 58 35 /** 59 * Converts a CIDR to Apache-escaped IP prefix regexes. 60 * 61 * /32 → "x\.y\.z\.w$" (exact IP) 62 * /24 → "x\.y\.z\." (octet prefix) 63 * /16 → "x\.y\." (two-octet prefix) 64 * /8 → "x\." (one-octet prefix) 65 * /15-/9 → multiple /16 prefixes (single-octet range expanded) 66 * 67 * Masks between /24 and /32 exclusive are skipped — expanding them 68 * would generate dozens of prefixes per subnet and blow up .htaccess. 69 * 70 * @param string $cidr 71 * @return array Apache-escaped prefix strings. 36 * Converts a CIDR block into .htaccess-compatible regex prefixes. 37 * 38 * Only IPv4 is supported. The returned strings are the LHS of 39 * mod_rewrite REMOTE_ADDR conditions (escaped dots included), so 40 * they can be used directly as `RewriteCond %{REMOTE_ADDR} ^<prefix>`. 41 * 42 * Rationale for the specific prefix lengths: 43 * /32 → exact match with trailing `$` 44 * /24 → first three octets + trailing dot (covers 256 IPs) 45 * /16 → first two octets + trailing dot 46 * /8 → single octet + trailing dot 47 * /17–/23 and non-/8-/16/-/24 masks cannot be expressed as a 48 * single prefix and are expanded into up to 64 host-prefixes. 49 * Anything outside /8–/32 is refused to keep the rule set small. 50 * 51 * @param string $cidr CIDR string, e.g. "192.168.1.0/24". 52 * @return array List of regex prefixes (empty on invalid input). 72 53 */ 73 54 function cybersec_htaccess_cidr_to_prefixes($cidr) { … … 95 76 return array($o[0] . '\\.'); 96 77 } 78 // /17–/23 cannot be expressed as a single octet-aligned prefix. 97 79 if ($mask > 16 && $mask < 24) { 98 80 return array(); 99 81 } 100 82 101 // /9 to /15 — expand to /16 prefixes 83 // /9–/15: expand to individual /16 prefixes (capped at 64 to keep 84 // the block size bounded). 102 85 $range = 1 << (16 - $mask); 103 86 $base = ((int) $o[0]) * 256 + ((int) $o[1]); … … 113 96 114 97 /** 115 * Builds the CyberPulse .htaccess block content. 116 * 117 * IP deny list comes from the 'secwall_permanent_blocked_subnets' option 118 * (30 most recent entries only). Path rules for .git/.env/etc. are static. 119 * 120 * Returns an empty string when: 121 * - the server does not read .htaccess (nginx, CLI with WP_CLI); 122 * - .htaccess is not writable; 123 * - the feature is disabled by the admin (opt-in). 124 * 125 * @return string Empty string when the block should not be written. 98 * Builds the .htaccess protection block from current settings. 99 * 100 * Returns an empty string when the feature is disabled, the server 101 * does not support .htaccess, or the file is not writable — callers 102 * must treat an empty return as "do nothing" rather than "write empty". 103 * 104 * The block does three things: 105 * 1. Blocks the top-30 recently-banned /24+ subnets (deny list), 106 * capped at 64 regex conditions to keep .htaccess small. 107 * 2. Blocks access to sensitive paths (.git, .env, SSH keys, 108 * crypto wallets, DB dumps, etc.) — defence-in-depth even if 109 * the PHP-level checks fail. 110 * 3. Blocks known AI / data-scraping bots by User-Agent. This 111 * happens before PHP runs, saving server resources. 112 * 113 * Server's own IP is always excluded from the deny conditions so 114 * the site cannot lock itself out. 115 * 116 * @return string The complete BEGIN/END-wrapped block, or ''. 126 117 */ 127 118 function cybersec_htaccess_build_block() { 128 119 if (!cybersec_htaccess_server_supports()) return ''; 129 120 130 // OPT-IN gate: never produce rules unless the admin explicitly 131 // enabled .htaccess protection in Settings. This keeps fresh 132 // installs and upgrades side-effect free. 121 // OPT-IN gate: never produce rules unless the admin explicitly enabled it. 133 122 if (function_exists('cybersec_get_settings')) { 134 123 $settings = cybersec_get_settings(); … … 145 134 $server_ip = function_exists('cybersec_get_server_ip') ? cybersec_get_server_ip() : ''; 146 135 136 // Collect CIDR prefixes from the 30 most recent permabans. 137 // Sorting by blocked_at DESC keeps the freshest threats present 138 // when the 64-condition cap is hit. 147 139 $deny_prefixes = array(); 148 140 $permanent = get_option('secwall_permanent_blocked_subnets', array()); 149 141 if (!empty($permanent) && is_array($permanent)) { 150 // Most recent 30 subnets only — keep .htaccess compact151 142 uasort($permanent, function($a, $b) { 152 143 $ta = isset($a['blocked_at']) ? strtotime($a['blocked_at']) : 0; … … 166 157 $block = CYBERPULSE_HTACCESS_BEGIN . "\n"; 167 158 $block .= "# Generated: " . gmdate('Y-m-d H:i:s') . " UTC\n"; 159 160 // Assign our custom 403 page 161 $block .= "ErrorDocument 403 /cyberpulse-403.html\n\n"; 162 168 163 $block .= "<IfModule mod_rewrite.c>\n"; 169 164 $block .= "RewriteEngine On\n"; 170 165 166 // ============================================================ 167 // PERMABAN DENY LIST 168 // Server's own IP is excluded first so a misconfigured ban of 169 // its own subnet cannot break admin access. 170 // ============================================================ 171 171 if (!empty($deny_prefixes)) { 172 // Never block the server's own IP (self-requests from cron, monitoring, etc.)173 172 if ($server_ip && filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { 174 173 $block .= "RewriteCond %{REMOTE_ADDR} !^" . str_replace('.', '\\.', $server_ip) . "$\n"; … … 181 180 } 182 181 182 // ============================================================ 183 // SENSITIVE CONFIG & SYSTEM FILES 184 // ============================================================ 185 183 186 // Configuration files that must NEVER be exposed to the web. 184 187 // Apache usually blocks .htaccess via <FilesMatch "^\.ht"> in the … … 193 196 $block .= "RewriteRule (^|/)(readme|license|changelog)\\.(html|txt|md)$ - [F,L,NC]\n"; 194 197 195 // Path rules — only files/dirs that are NEVER legitimate to expose.196 // /graphql and /userfiles are intentionally excluded — they break197 // WPGraphQL, Gatsby, Next.js, and CMS platforms with /userfiles/ dirs.198 // VCS directories, env/secret files, SSH keys, crypto wallets, 199 // container/IDE probes, and DB dumps. Runs before PHP, so it 200 // catches scanners that would otherwise hit PHP and log. 198 201 $block .= "RewriteRule (^|/)\\.git(/|$) - [F,L]\n"; 199 202 $block .= "RewriteRule (^|/)\\.svn(/|$) - [F,L]\n"; … … 211 214 $block .= "RewriteRule (^|/)@fs(/|$) - [F,L]\n"; 212 215 $block .= "RewriteRule (^|/)proc/self(/|$) - [F,L]\n"; 216 217 // wp-config backups — covers wp-config.bak, wp-config.php.bak, 218 // wp-config.php.zip, wp-config.php.tar.gz, etc. 213 219 $block .= "RewriteRule (^|/)wp-config(\\.php)?\\.(bak|old|txt|save|orig|tmp|swp|zip|tar\\.gz)$ - [F,L]\n"; 220 214 221 $block .= "RewriteRule (^|/)(database|dump|db|users|backup)\\.sql$ - [F,L]\n"; 215 222 216 // Build the AI-bot regex from the ACTIVE signatures only, 217 // respecting the ai_training_block_enabled / ai_search_block_enabled 218 // toggles. When both are off, this whole section is skipped. 223 // ============================================================ 224 // AI / DATA-SCRAPING BOT BLOCK 225 // Fires before PHP. Signatures come from the ACTIVE list only, 226 // respecting ai_training_block_enabled / ai_search_block_enabled. 227 // When both are off, this section is skipped entirely. 228 // ============================================================ 219 229 $active_ai = function_exists('cybersec_get_active_ai_bot_signatures') 220 230 ? cybersec_get_active_ai_bot_signatures() 221 231 : array(); 222 232 223 if (!empty($active_ai)) {233 if (!empty($active_ai)) { 224 234 // preg_quote: protects against regex injection. 225 235 // str_replace: replaces literal spaces (e.g. "IAS Crawler") … … 232 242 } 233 243 $bot_ua = '(' . implode('|', $escaped) . ')'; 244 245 // Exclude the custom 403 HTML page, its CSS and JS files 246 // to prevent infinite loops and broken styling. 247 $block .= "RewriteCond %{REQUEST_URI} !/cyberpulse-403\\.html [NC]\n"; 248 $block .= "RewriteCond %{REQUEST_URI} !/cyberpulse-403\\.css [NC]\n"; 249 $block .= "RewriteCond %{REQUEST_URI} !/cyberpulse-403\\.js [NC]\n"; 234 250 $block .= "RewriteCond %{HTTP_USER_AGENT} " . $bot_ua . " [NC]\n"; 235 251 $block .= "RewriteRule .* - [F,L]\n\n"; … … 243 259 244 260 /** 245 * Inserts or updates the CyberPulse block in .htaccess. 246 * 247 * The block is placed BEFORE "# BEGIN WordPress" so deny rules are 248 * evaluated before WP's "if file exists" catch-all. 249 * 250 * @param bool $verify Perform a test GET after writing and roll back on 5xx. 251 * Pass false during activation — WordPress is in 252 * maintenance mode and the verify-request would 5xx, 253 * causing a false rollback. 254 * @return bool 261 * Returns a data-URI SVG favicon for the static 403 page. 262 * 263 * Inlined so the favicon renders even when the visitor's IP is 264 * blocked at the .htaccess level and every external request 265 * (including /favicon.ico) returns 403. No network round-trip, 266 * no dependency on WordPress being bootstrapped. 267 * 268 * @return string `data:image/svg+xml,...` URI ready for <link rel="icon">. 269 */ 270 function cybersec_htaccess_favicon_data_uri() { 271 static $uri = null; 272 if ($uri !== null) return $uri; 273 274 $svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">' 275 . '<path d="M 18.0,4.5 C 10.9,4.5 6.8,6.8 6.8,10.4 C 7.0,25.8 16.0,30.9 18.0,32.3 C 20.0,30.9 29.0,25.8 29.2,10.4 C 29.2,6.8 25.1,4.5 18.0,4.5 Z"' 276 . ' fill="#1a1e18" stroke="#00e048" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>' 277 . '<path fill="none" stroke="#00e048" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"' 278 . ' d="M 9.0,18.0 L 13.2,18.0 L 15.0,14.0 L 18.0,23.6 L 21.0,10.0 L 22.8,18.0 L 27.0,18.0"/>' 279 . '</svg>'; 280 281 $uri = 'data:image/svg+xml;charset=utf-8,' . rawurlencode($svg); 282 return $uri; 283 } 284 285 /** 286 * Writes the protection block into .htaccess and optionally verifies it. 287 * 288 * Uses WordPress's BEGIN/END markers to replace an existing block 289 * in place. New blocks are placed BEFORE the `# BEGIN WordPress` 290 * marker so they can deny access before WP rewrite rules run. 291 * 292 * Two safety measures: 293 * - Whitespace-in-UA-regex guard: if the built block contains a 294 * literal space inside the bot UA condition, .htaccess parsing 295 * would fail and break the whole site. Refuses to write. 296 * - Optional HTTP verification: sends a request to the front page. 297 * On 5xx (500/502/504) the original .htaccess is restored, so a 298 * bad rule cannot leave the site offline. 299 * 300 * Errors are stored in the `cybersec_htaccess_sync_error` transient 301 * for 5 minutes and surfaced via the AJAX handler / admin error panel. 302 * 303 * @param bool $verify Run the HTTP self-test after writing. 304 * @return bool True on success, false on any failure. 255 305 */ 256 306 function cybersec_htaccess_sync($verify = true) { … … 266 316 } 267 317 268 // Safety: RewriteCond patterns must not contain literal spaces. 269 // A space inside the regex group is parsed by Apache as an extra 270 // argument and causes 500 Internal Server Error on every request. 318 // Whitespace inside the UA condition would break Apache parsing. 319 // Fail closed rather than write an invalid .htaccess. 271 320 if (strpos($block, 'RewriteCond %{HTTP_USER_AGENT}') !== false) { 272 321 if (!preg_match('/RewriteCond\s+%\{HTTP_USER_AGENT\}\s+\S+\s+\[NC\]/', $block)) { … … 279 328 } 280 329 330 // ============================================================ 331 // GENERATE STATIC 403 PAGE 332 // We use a distinct filename (cyberpulse-403.html) so we never 333 // overwrite a custom 403.html that the user might already have. 334 // 335 // This file is served directly by Apache via ErrorDocument — it 336 // does NOT go through WordPress, so wp_enqueue_style() and 337 // wp_enqueue_script() are unavailable. To comply with Plugin 338 // Check (WordPress.WP.EnqueuedResources.*) and keep the page 339 // fully self-contained, the CSS and JS are embedded inline 340 // instead of being loaded via <link>/<script src>. 341 // 342 // Same pattern as cybersec_show_unified_block_page() in 343 // cyberpulse-core.php — that path is already Plugin-Check clean. 344 // 345 // The favicon is also a data URI (cybersec_htaccess_favicon_data_uri): 346 // a normal /favicon.ico request would be blocked by the same 347 // permaban / AI-bot rule that produced this page, so the icon 348 // must be embedded rather than linked. 349 // ============================================================ 350 $html_403_path = ABSPATH . 'cyberpulse-403.html'; 351 if (!cybersec_fs_exists($html_403_path)) { 352 $lang = substr(cybersec_get_locale(), 0, 2); 353 354 $css_path = plugin_dir_path(__FILE__) . 'assets/css/cyberpulse-403.css'; 355 $js_path = plugin_dir_path(__FILE__) . 'assets/js/cyberpulse-403.js'; 356 357 $inline_css = cybersec_fs_get_contents($css_path); 358 $inline_js = cybersec_fs_get_contents($js_path); 359 360 // Minify inline CSS — identical to cybersec_show_unified_block_page(). 361 // Safe regex: strips comments, collapses whitespace, tightens around 362 // structural symbols. calc() operators keep their spaces because 363 // they're not in the [{};:,>] class. 364 if (!empty($inline_css)) { 365 $inline_css = preg_replace('#/\*.*?\*/#s', '', $inline_css); 366 $inline_css = preg_replace('/\s+/', ' ', $inline_css); 367 $inline_css = preg_replace('/\s*([{};:,>])\s*/', '$1', $inline_css); 368 $inline_css = trim($inline_css); 369 } 370 371 $favicon_uri = cybersec_htaccess_favicon_data_uri(); 372 373 $html_403 = '<!DOCTYPE html> 374 <html lang="' . esc_attr($lang) . '"> 375 <head> 376 <meta charset="UTF-8"> 377 <meta name="robots" content="noindex,nofollow,noarchive"> 378 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 379 <title>403 Forbidden | CyberPulse Security</title> 380 <link rel="icon" type="image/svg+xml" href="' . esc_attr($favicon_uri) . '"> 381 <style>' . $inline_css . '</style> 382 </head> 383 <body> 384 <div class="sw-card"> 385 <div class="sw-icon"> 386 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff4040" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 387 <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/> 388 </svg> 389 </div> 390 <h1 class="sw-title" id="cp-403-title">403 ' . esc_html(cybersec_translate('Access Denied')) . '</h1> 391 <p class="sw-description" id="cp-403-desc">' . esc_html(cybersec_translate('Your request was blocked by the server security system.')) . '</p> 392 <a href="javascript:location.reload();" class="sw-btn" id="cp-403-btn">' . esc_html(cybersec_translate('Refresh Page')) . '</a> 393 <div class="sw-footer"> 394 <a href="https://cyberpulse-security.com" target="_blank" rel="noopener" class="sw-brand"> 395 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" fill="none"> 396 <path d="M 18.0,4.5 C 10.9,4.5 6.8,6.8 6.8,10.4 C 7.0,25.8 16.0,30.9 18.0,32.3 C 20.0,30.9 29.0,25.8 29.2,10.4 C 29.2,6.8 25.1,4.5 18.0,4.5 Z" fill="none" stroke="#00e048" stroke-width="2"/> 397 <path fill="none" stroke="#00e048" stroke-width="1.6" d="M 9.0,18.0 L 13.2,18.0 L 15.0,14.0 L 18.0,23.6 L 21.0,10.0 L 22.8,18.0 L 27.0,18.0"/> 398 </svg> 399 Protected by CyberPulse 400 </a> 401 </div> 402 </div> 403 <script>' . $inline_js . '</script> 404 </body> 405 </html>'; 406 cybersec_fs_put_contents($html_403_path, $html_403); 407 } 408 281 409 $htaccess_path = ABSPATH . '.htaccess'; 282 410 … … 294 422 } 295 423 424 // Strip any existing CyberPulse block first so we do not duplicate. 296 425 $pattern = '/' . preg_quote(CYBERPULSE_HTACCESS_BEGIN, '/') . '.*?' . preg_quote(CYBERPULSE_HTACCESS_END, '/') . "\n?/s"; 297 426 $content = preg_replace($pattern, '', $original); 298 427 428 // Insert before the WordPress block so our F,L rules win. 299 429 $wp_marker = '# BEGIN WordPress'; 300 430 $pos = strpos($content, $wp_marker); … … 319 449 } 320 450 451 // ============================================================ 452 // SELF-TEST 453 // Fetch the front page. A 5xx response almost certainly means 454 // our new rules broke the server — roll back to the original. 455 // 4xx is fine (auth-protected sites, 404 on non-existent query 456 // string, etc.) and does not trigger rollback. 457 // ============================================================ 321 458 $verify_resp = wp_remote_get(home_url('/?cyberpulse_verify=' . wp_rand(1000, 9999)), array( 322 459 'timeout' => 5, … … 329 466 )); 330 467 331 if (!is_wp_error($verify_resp)) {468 if (!is_wp_error($verify_resp)) { 332 469 $code = wp_remote_retrieve_response_code($verify_resp); 333 470 if (in_array($code, array(500, 502, 504))) { … … 347 484 348 485 /** 349 * Removes the CyberPulse block from .htaccess (used on deactivation350 * and when the admin unchecks the option in Settings).351 * 352 * Only the plugin's own markers are touched — other plugins' blocks353 * stay intact.354 * 355 * @return bool 486 * Removes the CyberPulse block from .htaccess. 487 * 488 * Uses the BEGIN/END markers so user-added rules above or below the 489 * block are preserved untouched. Safe to call when no block exists 490 * (returns true) or when .htaccess is missing (returns true). 491 * 492 * @return bool True if the file no longer contains a CyberPulse block. 356 493 */ 357 494 function cybersec_htaccess_remove() { 495 // Clean up the static 403 page we generated 496 $html_403_path = ABSPATH . 'cyberpulse-403.html'; 497 if (cybersec_fs_exists($html_403_path)) { 498 cybersec_fs_delete($html_403_path); 499 } 500 358 501 $htaccess_path = ABSPATH . '.htaccess'; 359 502 if (!cybersec_fs_exists($htaccess_path)) return true; … … 370 513 } 371 514 372 // ------------------------------------------------------------------373 // AJAX: manual sync button 374 / / ------------------------------------------------------------------375 376 /**377 * AJAX: rewrites the plugin's .htaccess block. Returns a JSON error when378 * th e server does not read .htaccess (nginx), the feature is disabled,379 * or the write fails — the latter rolls back automatically inside380 * cybersec_htaccess_sync().381 */ 382 add_action('wp_ajax_cyber sec_htaccess_sync', function() {515 // ==================== AJAX: MANUAL SYNC ==================== 516 517 /** 518 * AJAX: writes .htaccess rules on demand from the admin UI. 519 * 520 * Requires the "htaccess_protection_enabled" option to be ON — 521 * this is a safety check, not just a convenience: the admin must 522 * have explicitly opted in before we touch .htaccess. On failure 523 * the transient error reason is surfaced in the JSON response. 524 */ 525 add_action('wp_ajax_cyberpulse_htaccess_sync', function() { 383 526 $nonce_action = defined('CYBERPULSE_AJAX_NONCE_ACTION') ? CYBERPULSE_AJAX_NONCE_ACTION : 'cybersec_ajax_action'; 384 527 check_ajax_referer($nonce_action, 'nonce'); … … 387 530 } 388 531 389 // Feature must be explicitly enabled in Settings. If the admin 390 // clicks the "Sync" button while the option is off, refuse rather 391 // than silently writing rules they didn't ask for. 392 $settings = function_exists('cybersec_get_settings') ? cybersec_get_settings() : array(); 532 $settings = cybersec_get_settings(); 393 533 if (empty($settings['htaccess_protection_enabled'])) { 394 wp_send_json_error(array( 395 'message' => 'Enable .htaccess protection in Settings first.', 396 )); 534 wp_send_json_error(array('message' => 'Enable .htaccess protection in Settings first.')); 397 535 } 398 536 … … 416 554 }); 417 555 418 /** 419 * Runs on every admin_init: performs the one-time legacy cleanup for 420 * installations upgraded from a version that wrote the block 421 * unconditionally, and re-syncs .htaccess when the plugin version 422 * changed and the feature is enabled. 556 // ==================== AUTO-SYNC ON VERSION CHANGE ==================== 557 558 /** 559 * Hooked on `admin_init` priority 20. 560 * 561 * Responsibilities: 562 * 1. One-time cleanup of legacy blocks if the feature is now 563 * disabled (migration from an older build that shipped rules 564 * unconditionally). 565 * 2. Automatic re-sync when the plugin version changes, so the 566 * block stays in sync with the current deny list / bot list. 567 * Stores the sync state (or error) for admin visibility. 568 * 569 * Runs ONLY when the feature is enabled — otherwise it just cleans 570 * up and exits. 423 571 */ 424 572 add_action('admin_init', function() { … … 426 574 $enabled = !empty($settings['htaccess_protection_enabled']); 427 575 428 // One-time migration for users upgrading from a version where the 429 // block was written unconditionally. If the option is now off but a 430 // legacy block still exists in .htaccess, remove it once so nobody 431 // keeps stale rules they never asked for. 576 // One-time migration: remove legacy blocks if the feature was disabled. 432 577 if (!$enabled && !get_option('cybersec_htaccess_legacy_purged')) { 433 578 $htaccess_path = ABSPATH . '.htaccess'; … … 444 589 if (!$enabled) return; 445 590 446 // Version check — rewrite only when the plugin version changed. 447 $stored = get_option('cybersec_htaccess_version', ''); 448 $current = defined('CYBERSEC_VERSION') ? CYBERSEC_VERSION : '0'; 591 // Version guard — avoid touching .htaccess on every admin page load. 592 $stored = get_option('cybersec_htaccess_version', ''); 593 $current = defined('CYBERPULSE_PRO_VERSION') ? CYBERPULSE_PRO_VERSION : (defined('CYBERSEC_VERSION') ? CYBERSEC_VERSION : '0'); 594 449 595 if ($stored === $current) return; 450 596 -
cyberpulse/trunk/cyberpulse-tabs.php
r3763154 r3764759 260 260 'ai_training_block_enabled' => isset($_POST['cybersec_ai_training_block_enabled']) ? 1 : 0, 261 261 'ai_search_block_enabled' => isset($_POST['cybersec_ai_search_block_enabled']) ? 1 : 0, 262 'force_https' => isset($_POST['cybersec_force_https']) ? 1 : 0, 262 263 ); 263 264 … … 1004 1005 $fsize = filesize($audit_log); 1005 1006 if ($fsize > 0) { 1006 // v5.9.1.1 — read tail via WP_Filesystem instead of1007 // fopen/fseek/fread/fclose (Plugin Check1008 // WordPress.WP.AlternativeFunctions.file_system_operations_*).1009 1007 $full = cybersec_fs_get_contents($audit_log); 1010 1008 if ($full !== '') { … … 2038 2036 <p style="margin-top:8px;font-size:11px;color:var(--sw-success);"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:baseline;margin-right:3px;position:relative;top:1.5px;"><polyline points="20 6 9 17 4 12"/></svg><?php echo esc_html(cybersec_translate('Always active')); ?></p> 2039 2037 </div> 2038 <div class="sw-settings-card" style="grid-column: 1 / -1;"> 2039 <h4><?php echo esc_html(cybersec_translate('Force HTTPS')); ?> <span class="sw-status <?php echo !empty($st['force_https']) ? 'sw-status-active' : 'sw-status-inactive'; ?>"><?php echo !empty($st['force_https']) ? esc_html(cybersec_translate('Enabled')) : esc_html(cybersec_translate('Disabled')); ?></span></h4> 2040 <p><?php echo esc_html(cybersec_translate('Automatically redirects all HTTP requests to HTTPS (301 redirect).')); ?> <strong><?php echo esc_html(cybersec_translate('Enable only if you have an SSL certificate configured')); ?></strong>, <?php echo esc_html(cybersec_translate('otherwise the site will become inaccessible.')); ?></p> 2041 <label style="margin-top:8px;display:block;"><input type="checkbox" name="cybersec_force_https" value="1" <?php checked(!empty($st['force_https']), true); ?>> <?php echo esc_html(cybersec_translate('Redirect HTTP → HTTPS')); ?></label> 2042 </div> 2040 2043 </div> 2041 2044 </div> … … 2069 2072 <strong style="color:var(--sw-accent);"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:baseline;margin-right:3px;position:relative;top:2px;"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><polyline points="13 2 9 10 12 10 8 18"/></svg><?php echo esc_html(cybersec_translate('Flood and DDoS Protection')); ?></strong> 2070 2073 <p style="margin:6px 0 0 0;font-size:12px;color:var(--sw-text-secondary);line-height:1.5;"><?php echo esc_html(cybersec_translate('Three levels of application-layer attack protection.')); ?> <strong><?php echo esc_html(cybersec_translate('Basic')); ?></strong> — <?php echo esc_html(cybersec_translate('constant protection against scraping and flooding.')); ?> <strong><?php echo esc_html(cybersec_translate('Enhanced')); ?></strong> — <?php echo esc_html(cybersec_translate('for repelling DDoS attacks.')); ?> <strong>Anti-Slowloris</strong> — <?php echo esc_html(cybersec_translate('automatic protection against slow connections.')); ?></p> 2071 <div style="background:var(--sw-success-light);border:2px solid var(--sw-success-border);border-radius:var(--sw-radius);padding:14px 16px;margin-top:12px;"><strong style="color:var(--sw-success);"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:baseline;margin-right:3px;position:relative;top:1.5px;"><polyline points="20 6 9 17 4 12"/></svg><?php echo esc_html(cybersec_translate('Basic Level (Rate Limiting)')); ?></strong><p style="margin:6px 0 0 0;font-size:12px;color:var(--sw-text-secondary);"><?php echo esc_html(cybersec_translate('Limits the number of requests from one IP to the entire site within a specified time interval. Protects against DDoS attacks and aggressive scraping. After 3 repeated violations, the subnet is automatically permanently banned.')); ?> <strong><?php echo esc_html(cybersec_translate('Recommended: enabled, 60 requests per 60 seconds.')); ?></strong></p><label style="margin-top:10px;display:block;"><input type="checkbox" name="cybersec_rate_limiting_enabled" value="1" <?php checked($st['rate_limiting_enabled'],1);?>> <?php echo esc_html(cybersec_translate('Enable basic protection')); ?></label><div style="margin-top:10px;display:flex;align-items:center;gap:6px;flex-wrap:wrap;"><span><?php echo esc_html(cybersec_translate('Maximum')); ?></span><input type="number" name="cybersec_rate_limit_requests" value="<?php echo (int)$st['rate_limit_requests'];?>" min="1" max="1000" style="width:80px;"><span><?php echo esc_html(cybersec_translate('requests per')); ?></span><input type="number" name="cybersec_rate_limit_window" value="<?php echo (int)$st['rate_limit_window'];?>" min="1" max="3600" style="width:80px;"><span><?php echo esc_html(cybersec_translate('seconds')); ?></span></div></div> 2072 <div style="background:var(--sw-info-light);border:2px solid var(--sw-info-border);border-radius:var(--sw-radius);padding:14px 16px;margin-top:12px;"><strong style="color:var(--sw-info);"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:baseline;margin-right:3px;position:relative;top:1.5px;"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg><?php echo esc_html(cybersec_translate('Anti-Slowloris Protection')); ?></strong><p style="margin:6px 0 0 0;font-size:12px;color:var(--sw-text-secondary);"><?php echo esc_html(cybersec_translate('Automatically tracks and blocks slow connections (Slowloris attacks). Works automatically when enhanced DDoS protection is enabled. IP is blocked when exceeding')); ?> <strong><?php echo esc_html(cybersec_translate('20 simultaneous connections')); ?></strong>.</p></div> 2074 2075 <!-- ============ BASIC LEVEL ============ --> 2076 <div style="background:var(--sw-success-light);border:2px solid var(--sw-success-border);border-radius:var(--sw-radius);padding:14px 16px;margin-top:12px;"> 2077 <strong style="color:var(--sw-success);"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:baseline;margin-right:3px;position:relative;top:1.5px;"><polyline points="20 6 9 17 4 12"/></svg><?php echo esc_html(cybersec_translate('Basic Level (Rate Limiting)')); ?></strong> 2078 <p style="margin:6px 0 0 0;font-size:12px;color:var(--sw-text-secondary);"><?php echo esc_html(cybersec_translate('Limits the number of requests from one IP to the entire site within a specified time interval. Protects against DDoS attacks and aggressive scraping. After 3 repeated violations, the subnet is automatically permanently banned.')); ?> <strong><?php echo esc_html(cybersec_translate('Recommended: enabled, 40 requests per 60 seconds.')); ?></strong></p> 2079 2080 <label style="margin-top:10px;display:block;"><input type="checkbox" name="cybersec_rate_limiting_enabled" value="1" <?php checked($st['rate_limiting_enabled'],1);?>> <?php echo esc_html(cybersec_translate('Enable basic protection')); ?></label> 2081 2082 <div style="margin-top:10px;display:flex;align-items:center;gap:6px;flex-wrap:wrap;"><span><?php echo esc_html(cybersec_translate('Maximum')); ?></span><input type="number" name="cybersec_rate_limit_requests" value="<?php echo (int)$st['rate_limit_requests'];?>" min="1" max="1000" style="width:80px;"><span><?php echo esc_html(cybersec_translate('requests per')); ?></span><input type="number" name="cybersec_rate_limit_window" value="<?php echo (int)$st['rate_limit_window'];?>" min="1" max="3600" style="width:80px;"><span><?php echo esc_html(cybersec_translate('seconds')); ?></span></div> 2083 2084 <!-- Collapsible help: how to choose the right value --> 2085 <details style="margin-top:12px;padding:10px 12px;background:var(--sw-card-bg-alt);border:1px solid var(--sw-border);border-radius:var(--sw-radius);font-size:12px;color:var(--sw-text-secondary);line-height:1.6;"> 2086 <summary style="cursor:pointer;font-weight:700;color:var(--sw-text);outline:none;"> 2087 <?php echo esc_html(cybersec_translate('How to choose the right value')); ?> 2088 </summary> 2089 <ul style="margin:10px 0 0 16px;padding:0;"> 2090 <li style="margin-bottom:6px;"><strong>30–35</strong> — <?php echo esc_html(cybersec_translate('homogeneous audience, mostly desktop users, without mobile carriers.')); ?></li> 2091 <li style="margin-bottom:6px;"><strong>40</strong> — <?php echo esc_html(cybersec_translate('universal default, suitable for most news and information sites.')); ?></li> 2092 <li style="margin-bottom:6px;"><strong>50–80</strong> — <?php echo esc_html(cybersec_translate('large share of mobile-carrier traffic (CGNAT) or corporate networks.')); ?></li> 2093 </ul> 2094 <p style="margin:10px 0 0 0;"> 2095 <strong><?php echo esc_html(cybersec_translate('Important:')); ?></strong> 2096 <?php echo esc_html(cybersec_translate('the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.')); ?> 2097 </p> 2098 <p style="margin:8px 0 0 0;padding:8px 10px;background:var(--sw-info-light);border-left:3px solid var(--sw-info);border-radius:4px;"> 2099 <strong><?php echo esc_html(cybersec_translate('CGNAT (Carrier-Grade NAT):')); ?></strong> 2100 <?php echo esc_html(cybersec_translate('mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.')); ?> 2101 </p> 2102 </details> 2103 </div> 2104 2105 <!-- ============ ANTI-SLOWLORIS ============ --> 2106 <div style="background:var(--sw-info-light);border:2px solid var(--sw-info-border);border-radius:var(--sw-radius);padding:14px 16px;margin-top:12px;"> 2107 <strong style="color:var(--sw-info);"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:baseline;margin-right:3px;position:relative;top:1.5px;"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg><?php echo esc_html(cybersec_translate('Anti-Slowloris Protection')); ?></strong> 2108 <p style="margin:6px 0 0 0;font-size:12px;color:var(--sw-text-secondary);"><?php echo esc_html(cybersec_translate('Automatically tracks and blocks slow connections (Slowloris attacks). Works automatically when enhanced DDoS protection is enabled. IP is blocked when exceeding')); ?> <strong><?php echo esc_html(cybersec_translate('20 simultaneous connections')); ?></strong>.</p> 2109 </div> 2073 2110 </div> 2074 2111 </div> -
cyberpulse/trunk/cyberpulse.php
r3763154 r3764759 4 4 * Plugin URI: https://wordpress.org/plugins/cyberpulse 5 5 * Description: Real-time security heartbeat for your WordPress. Monitors every request, blocks bots instantly, protects against brute force and AI scraping. Feel the pulse of protection. Free version with PRO upgrade available. 6 * Version: 5.9.1. 26 * Version: 5.9.1.3 7 7 * Author: CyberPulse Security 8 8 * Author URI: https://cyberpulse-security.com -
cyberpulse/trunk/languages/cyberpulse-de_DE.php
r3763154 r3764759 830 830 'Automatically added administrator IP' => 'Automatisch hinzugefügte Administrator-IP', 831 831 'No manual entries yet.' => 'Noch keine manuellen Einträge.', 832 'Static file via bot UA' => 'Statische Datei über Bot User-Agent', 832 833 833 834 // ------------------------------------------------------------------ … … 1057 1058 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => 'Wird beim Speichern automatisch angewendet. Regeln werden entfernt, wenn das Häkchen entfernt wird. Andere .htaccess-Inhalte (WordPress, Caching-Plugins usw.) bleiben erhalten. Ein fehlgeschlagenes Schreiben wird überprüft und automatisch zurückgesetzt.', 1058 1059 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => 'Fügt Blockierungsregeln direkt zu .htaccess hinzu (nur Apache / LiteSpeed). Blockiert KI-Bots und sensible Dateien (.git, .env, .sql, Schlüssel, Backups), bevor PHP geladen wird, um Serverressourcen zu sparen. Die KI-Bot-Regeln folgen den beiden Schaltern oben – das Deaktivieren einer Kategorie entfernt sie auch aus .htaccess.', 1060 1061 // Force HTTPS 1062 'Force HTTPS' => 'HTTPS erzwingen', 1063 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'Leitet alle HTTP-Anfragen automatisch auf HTTPS um (301-Weiterleitung).', 1064 'Enable only if you have an SSL certificate configured' => 'Nur aktivieren, wenn ein SSL-Zertifikat konfiguriert ist', 1065 'otherwise the site will become inaccessible.' => 'andernfalls wird die Website unzugänglich.', 1066 'Redirect HTTP → HTTPS' => 'HTTP → HTTPS-Weiterleitung', 1067 1068 // Flood and DDoS Protection — Help Block 1069 'Recommended: enabled, 40 requests per 60 seconds.' => 'Empfohlen: aktiviert, 40 Anfragen pro 60 Sekunden.', 1070 'How to choose the right value' => 'So wählen Sie den richtigen Wert', 1071 'homogeneous audience, mostly desktop users, without mobile carriers.' => 'homogene Zielgruppe, überwiegend Desktop-Nutzer, ohne Mobilfunkanbieter.', 1072 'universal default, suitable for most news and information sites.' => 'universeller Standardwert, geeignet für die meisten Nachrichten- und Informationsseiten.', 1073 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'großer Anteil an Mobilfunkverkehr (CGNAT) oder Firmennetzwerken.', 1074 'Important:' => 'Wichtig:', 1075 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => 'der obige Wert gilt für normale Browser mit einem modernen User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). Für leere oder defekte User-Agents, Rechenzentrums-IPs, alte Browser und bekannte Bots wird das Limit automatisch 3–6× strenger angewendet.', 1076 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT):', 1077 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'Mobilfunkanbieter (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) und Firmennetzwerke weisen eine öffentliche IP Hunderten von Teilnehmern zu. Ein zu niedriges Limit blockiert echte Leser, nicht Angreifer.', 1059 1078 ); -
cyberpulse/trunk/languages/cyberpulse-en_US.php
r3763154 r3764759 802 802 'Enable ONLY if' => 'Enable ONLY if', 803 803 'you use Cloudflare (orange cloud enabled in DNS).' => 'you use Cloudflare (orange cloud enabled in DNS).', 804 'Static file via bot UA' => 'Static file via bot UA', 804 805 805 806 // ------------------------------------------------------------------ … … 1075 1076 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' 1076 1077 => 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.', 1078 1079 // Force HTTPS 1080 'Force HTTPS' => 'Force HTTPS', 1081 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'Automatically redirects all HTTP requests to HTTPS (301 redirect).', 1082 'Enable only if you have an SSL certificate configured' => 'Enable only if you have an SSL certificate configured', 1083 'otherwise the site will become inaccessible.' => 'otherwise the site will become inaccessible.', 1084 'Redirect HTTP → HTTPS' => 'Redirect HTTP → HTTPS', 1085 1086 // Flood and DDoS Protection — Help Block 1087 'Recommended: enabled, 40 requests per 60 seconds.' => 'Recommended: enabled, 40 requests per 60 seconds.', 1088 'How to choose the right value' => 'How to choose the right value', 1089 'homogeneous audience, mostly desktop users, without mobile carriers.' => 'homogeneous audience, mostly desktop users, without mobile carriers.', 1090 'universal default, suitable for most news and information sites.' => 'universal default, suitable for most news and information sites.', 1091 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'large share of mobile-carrier traffic (CGNAT) or corporate networks.', 1092 'Important:' => 'Important:', 1093 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.', 1094 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT):', 1095 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.', 1077 1096 ); -
cyberpulse/trunk/languages/cyberpulse-es_ES.php
r3763154 r3764759 802 802 'Enable ONLY if' => 'Activar SOLO si', 803 803 'you use Cloudflare (orange cloud enabled in DNS).' => 'usas Cloudflare (nube naranja activada en DNS).', 804 'Static file via bot UA' => 'Archivo estático vía User-Agent de bot', 804 805 805 806 // ------------------------------------------------------------------ … … 1055 1056 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => 'Se aplica automáticamente al guardar. Las reglas se eliminan cuando se desmarca. Se conserva el resto del contenido de .htaccess (WordPress, complementos de caché, etc.). Una escritura fallida se verifica y se revierte automáticamente.', 1056 1057 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => 'Agrega reglas de bloqueo directamente a .htaccess (solo Apache / LiteSpeed). Bloquea bots de IA y archivos confidenciales (.git, .env, .sql, claves, copias de seguridad) antes de que se cargue PHP, ahorrando recursos del servidor. Las reglas de los bots de IA siguen los dos interruptores anteriores: deshabilitar una categoría también la elimina de .htaccess.', 1058 1059 // Force HTTPS 1060 'Force HTTPS' => 'Forzar HTTPS', 1061 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'Redirige automáticamente todas las solicitudes HTTP a HTTPS (redirección 301).', 1062 'Enable only if you have an SSL certificate configured' => 'Habilitar solo si tiene un certificado SSL configurado', 1063 'otherwise the site will become inaccessible.' => 'de lo contrario, el sitio quedará inaccesible.', 1064 'Redirect HTTP → HTTPS' => 'Redirigir HTTP → HTTPS', 1065 1066 // Flood and DDoS Protection — Help Block 1067 'Recommended: enabled, 40 requests per 60 seconds.' => 'Recomendado: activado, 40 solicitudes por 60 segundos.', 1068 'How to choose the right value' => 'Cómo elegir el valor correcto', 1069 'homogeneous audience, mostly desktop users, without mobile carriers.' => 'audiencia homogénea, mayoritariamente usuarios de escritorio, sin operadores móviles.', 1070 'universal default, suitable for most news and information sites.' => 'valor predeterminado universal, adecuado para la mayoría de sitios de noticias e información.', 1071 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'gran proporción de tráfico de operadores móviles (CGNAT) o redes corporativas.', 1072 'Important:' => 'Importante:', 1073 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => 'el valor anterior se aplica a navegadores normales con un User-Agent moderno (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). Para User-Agents vacíos o rotos, IP de centros de datos, navegadores antiguos y bots conocidos, el límite se aplica automáticamente 3–6× más estricto.', 1074 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT):', 1075 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'los operadores móviles (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) y las redes corporativas asignan una IP pública a cientos de suscriptores. Un límite demasiado bajo bloqueará lectores reales, no atacantes.', 1057 1076 ); -
cyberpulse/trunk/languages/cyberpulse-fr_FR.php
r3763154 r3764759 802 802 'Enable ONLY if' => 'Activez UNIQUEMENT si', 803 803 'you use Cloudflare (orange cloud enabled in DNS).' => 'vous utilisez Cloudflare (nuage orange activé dans DNS).', 804 'Static file via bot UA' => 'Fichier statique via User-Agent de bot', 804 805 805 806 // ------------------------------------------------------------------ … … 1057 1058 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => 'Appliqué automatiquement lors de l\'enregistrement. Les règles sont supprimées lorsque la case est décochée. Le reste du contenu de .htaccess (WordPress, plugins de cache, etc.) est préservé. Un échec d\'écriture est vérifié et annulé automatiquement.', 1058 1059 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => 'Ajoute des règles de blocage directement dans .htaccess (Apache / LiteSpeed uniquement). Bloque les bots IA et les fichiers sensibles (.git, .env, .sql, clés, sauvegardes) avant même le chargement de PHP, économisant les ressources du serveur. Les règles des bots IA suivent les deux interrupteurs ci-dessus — la désactivation d\'une catégorie la supprime également de .htaccess.', 1060 1061 // Force HTTPS 1062 'Force HTTPS' => 'Forcer HTTPS', 1063 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'Redirige automatiquement toutes les requêtes HTTP vers HTTPS (redirection 301).', 1064 'Enable only if you have an SSL certificate configured' => 'Activer uniquement si un certificat SSL est configuré', 1065 'otherwise the site will become inaccessible.' => 'sinon le site deviendra inaccessible.', 1066 'Redirect HTTP → HTTPS' => 'Rediriger HTTP → HTTPS', 1067 1068 // Flood and DDoS Protection — Help Block 1069 'Recommended: enabled, 40 requests per 60 seconds.' => 'Recommandé : activé, 40 requêtes par 60 secondes.', 1070 'How to choose the right value' => 'Comment choisir la bonne valeur', 1071 'homogeneous audience, mostly desktop users, without mobile carriers.' => 'audience homogène, principalement des utilisateurs de bureau, sans opérateurs mobiles.', 1072 'universal default, suitable for most news and information sites.' => 'valeur par défaut universelle, adaptée à la plupart des sites d\'actualités et d\'information.', 1073 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'part importante du trafic d\'opérateurs mobiles (CGNAT) ou de réseaux d\'entreprise.', 1074 'Important:' => 'Important :', 1075 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => 'la valeur ci-dessus s\'applique aux navigateurs normaux avec un User-Agent moderne (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). Pour les User-Agents vides ou cassés, les IP de centres de données, les anciens navigateurs et les bots connus, la limite est appliquée automatiquement 3–6× plus strictement.', 1076 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT) :', 1077 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'les opérateurs mobiles (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) et les réseaux d\'entreprise attribuent une IP publique à des centaines d\'abonnés. Une limite trop basse bloquera de vrais lecteurs, pas les attaquants.', 1059 1078 ); -
cyberpulse/trunk/languages/cyberpulse-it_IT.php
r3763154 r3764759 800 800 'Enable ONLY if' => 'Abilita SOLO se', 801 801 'you use Cloudflare (orange cloud enabled in DNS).' => 'usi Cloudflare (cloud arancione abilitato nel DNS).', 802 'Static file via bot UA' => 'File statico tramite User-Agent bot', 802 803 803 804 // ------------------------------------------------------------------ … … 1043 1044 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => 'Applicato automaticamente al salvataggio. Le regole vengono rimosse quando la casella viene deselezionata. Il resto del contenuto di .htaccess (WordPress, plugin di caching, ecc.) viene preservato. Una scrittura fallita viene verificata e ripristinata automaticamente.', 1044 1045 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => 'Aggiunge regole di blocco direttamente in .htaccess (solo Apache / LiteSpeed). Blocca bot IA e file sensibili (.git, .env, .sql, chiavi, backup) prima ancora che PHP venga caricato, risparmiando risorse del server. Le regole dei bot IA seguono i due interruttori sopra — la disabilitazione di una categoria la rimuove anche da .htaccess.', 1046 1047 // Force HTTPS 1048 'Force HTTPS' => 'Forza HTTPS', 1049 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'Reindirizza automaticamente tutte le richieste HTTP a HTTPS (reindirizzamento 301).', 1050 'Enable only if you have an SSL certificate configured' => 'Abilita solo se hai configurato un certificato SSL', 1051 'otherwise the site will become inaccessible.' => 'altrimenti il sito diventerà inaccessibile.', 1052 'Redirect HTTP → HTTPS' => 'Reindirizza HTTP → HTTPS', 1053 1054 // Flood and DDoS Protection — Help Block 1055 'Recommended: enabled, 40 requests per 60 seconds.' => 'Consigliato: attivo, 40 richieste per 60 secondi.', 1056 'How to choose the right value' => 'Come scegliere il valore giusto', 1057 'homogeneous audience, mostly desktop users, without mobile carriers.' => 'pubblico omogeneo, prevalentemente utenti desktop, senza operatori mobili.', 1058 'universal default, suitable for most news and information sites.' => 'valore predefinito universale, adatto alla maggior parte dei siti di notizie e informazione.', 1059 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'grande quota di traffico da operatori mobili (CGNAT) o reti aziendali.', 1060 'Important:' => 'Importante:', 1061 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => 'il valore sopra si applica ai browser normali con User-Agent moderno (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). Per User-Agent vuoti o corrotti, IP di datacenter, browser obsoleti e bot noti, il limite viene applicato automaticamente 3–6× più severo.', 1062 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT):', 1063 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'gli operatori mobili (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) e le reti aziendali assegnano un IP pubblico a centinaia di abbonati. Un limite troppo basso bloccherà lettori reali, non gli aggressori.', 1045 1064 ); -
cyberpulse/trunk/languages/cyberpulse-ja.php
r3763154 r3764759 828 828 'Enable ONLY if' => '次の場合のみ有効にする', 829 829 'you use Cloudflare (orange cloud enabled in DNS).' => 'Cloudflareを使用している(DNSでオレンジ色の雲が有効)。', 830 'Static file via bot UA' => 'ボットのUser-Agentによる静的ファイルアクセス', 830 831 831 832 // ------------------------------------------------------------------ … … 1057 1058 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => '保存時に自動的に適用されます。チェックを外すとルールが削除されます。他の.htaccessの内容(WordPress、キャッシュプラグインなど)は保持されます。書き込みに失敗した場合は検証され、自動的にロールバックされます。', 1058 1059 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => 'ブロックルールを.htaccessに直接追加します(Apache / LiteSpeedのみ)。PHPが読み込まれる前にAIボットと機密ファイル(.git、.env、.sql、キー、バックアップ)をブロックし、サーバーリソースを節約します。AIボットのルールは上記の2つのトグルに従います — カテゴリを無効にすると.htaccessからも削除されます。', 1060 1061 // Force HTTPS 1062 'Force HTTPS' => 'HTTPSを強制する', 1063 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'すべてのHTTPリクエストをHTTPSに自動リダイレクトします(301リダイレクト)。', 1064 'Enable only if you have an SSL certificate configured' => 'SSL証明書が設定されている場合のみ有効にしてください', 1065 'otherwise the site will become inaccessible.' => 'そうでない場合、サイトにアクセスできなくなります。', 1066 'Redirect HTTP → HTTPS' => 'HTTP → HTTPS リダイレクト', 1067 1068 // Flood and DDoS Protection — Help Block 1069 'Recommended: enabled, 40 requests per 60 seconds.' => '推奨:有効、60 秒あたり 40 リクエスト。', 1070 'How to choose the right value' => '適切な値の選び方', 1071 'homogeneous audience, mostly desktop users, without mobile carriers.' => '均質なオーディエンス、主にデスクトップユーザー、モバイルキャリアなし。', 1072 'universal default, suitable for most news and information sites.' => '汎用的なデフォルト値、ほとんどのニュース・情報サイトに適しています。', 1073 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'モバイルキャリア(CGNAT)または企業ネットワークのトラフィックが多い場合。', 1074 'Important:' => '重要:', 1075 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => '上記の値は、最新の User-Agent(Chrome 90+、Firefox 90+、Safari 14+、Edge 90+)を使用する通常のブラウザに適用されます。空または壊れた User-Agent、データセンター IP、古いブラウザ、既知のボットには、制限が自動的に 3〜6 倍厳しく適用されます。', 1076 'CGNAT (Carrier-Grade NAT):' => 'CGNAT(キャリアグレード NAT):', 1077 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'モバイルキャリア(MTS、MegaFon、Beeline、Airtel、Claro、Jio、Vivo)と企業ネットワークは、1 つのパブリック IP を数百の加入者に割り当てます。制限が低すぎると、攻撃者ではなく実際の読者をブロックします。', 1059 1078 ); -
cyberpulse/trunk/languages/cyberpulse-ko_KR.php
r3763154 r3764759 824 824 'Enable ONLY if' => '다음 경우에만 활성화', 825 825 'you use Cloudflare (orange cloud enabled in DNS).' => 'Cloudflare를 사용 중인 경우 (DNS에서 주황색 구름 활성화).', 826 'Static file via bot UA' => '봇 User-Agent를 통한 정적 파일 접근', 826 827 827 828 // ------------------------------------------------------------------ … … 1040 1041 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => '저장 시 자동으로 적용됩니다. 선택을 취소하면 규칙이 제거됩니다. 기타 .htaccess 콘텐츠(WordPress, 캐싱 플러그인 등)는 보존됩니다. 쓰기 실패는 확인 후 자동으로 롤백됩니다.', 1041 1042 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => '차단 규칙을 .htaccess에 직접 추가합니다(Apache / LiteSpeed 전용). PHP가 로드되기 전에 AI 봇 및 민감한 파일(.git, .env, .sql, 키, 백업)을 차단하여 서버 리소스를 절약합니다. AI 봇 규칙은 위의 두 토글을 따릅니다 — 범주를 비활성화하면 .htaccess에서도 제거됩니다.', 1043 1044 // Force HTTPS 1045 'Force HTTPS' => 'HTTPS 강제', 1046 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => '모든 HTTP 요청을 HTTPS로 자동 리디렉션합니다 (301 리디렉션).', 1047 'Enable only if you have an SSL certificate configured' => 'SSL 인증서가 구성된 경우에만 활성화하세요', 1048 'otherwise the site will become inaccessible.' => '그렇지 않으면 사이트에 액세스할 수 없게 됩니다.', 1049 'Redirect HTTP → HTTPS' => 'HTTP → HTTPS 리디렉션', 1050 1051 // Flood and DDoS Protection — Help Block 1052 'Recommended: enabled, 40 requests per 60 seconds.' => '권장: 활성화됨, 60초당 40회 요청.', 1053 'How to choose the right value' => '올바른 값을 선택하는 방법', 1054 'homogeneous audience, mostly desktop users, without mobile carriers.' => '동질적인 사용자층, 주로 데스크톱 사용자, 모바일 통신사 없음.', 1055 'universal default, suitable for most news and information sites.' => '범용 기본값, 대부분의 뉴스 및 정보 사이트에 적합합니다.', 1056 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => '모바일 통신사(CGNAT) 또는 기업 네트워크 트래픽이 많은 경우.', 1057 'Important:' => '중요:', 1058 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => '위 값은 최신 User-Agent(Chrome 90+, Firefox 90+, Safari 14+, Edge 90+)를 사용하는 일반 브라우저에 적용됩니다. 비어 있거나 손상된 User-Agent, 데이터센터 IP, 구형 브라우저 및 알려진 봇에는 제한이 자동으로 3–6배 더 엄격하게 적용됩니다.', 1059 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT):', 1060 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => '모바일 통신사(MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo)와 기업 네트워크는 하나의 공인 IP를 수백 명의 가입자에게 할당합니다. 제한이 너무 낮으면 공격자가 아닌 실제 독자를 차단합니다.', 1042 1061 ); -
cyberpulse/trunk/languages/cyberpulse-pt_BR.php
r3763154 r3764759 824 824 'Enable ONLY if' => 'Ative SOMENTE se', 825 825 'you use Cloudflare (orange cloud enabled in DNS).' => 'você usa Cloudflare (nuvem laranja ativada no DNS).', 826 'Static file via bot UA' => 'Arquivo estático via User-Agent de bot', 826 827 827 828 // ------------------------------------------------------------------ … … 1053 1054 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => 'Aplicado automaticamente ao salvar. As regras são removidas quando desmarcadas. O restante do conteúdo do .htaccess (WordPress, plugins de cache, etc.) é preservado. Uma gravação com falha é verificada e revertida automaticamente.', 1054 1055 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => 'Adiciona regras de bloqueio diretamente ao .htaccess (apenas Apache / LiteSpeed). Bloqueia bots de IA e arquivos confidenciais (.git, .env, .sql, chaves, backups) antes mesmo de o PHP carregar, economizando recursos do servidor. As regras de bots de IA seguem os dois botões acima — desativar uma categoria também a remove do .htaccess.', 1056 1057 // Force HTTPS 1058 'Force HTTPS' => 'Forçar HTTPS', 1059 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'Redireciona automaticamente todas as solicitações HTTP para HTTPS (redirecionamento 301).', 1060 'Enable only if you have an SSL certificate configured' => 'Ative apenas se você tiver um certificado SSL configurado', 1061 'otherwise the site will become inaccessible.' => 'caso contrário, o site ficará inacessível.', 1062 'Redirect HTTP → HTTPS' => 'Redirecionar HTTP → HTTPS', 1063 1064 // Flood and DDoS Protection — Help Block 1065 'Recommended: enabled, 40 requests per 60 seconds.' => 'Recomendado: ativado, 40 requisições por 60 segundos.', 1066 'How to choose the right value' => 'Como escolher o valor correto', 1067 'homogeneous audience, mostly desktop users, without mobile carriers.' => 'público homogêneo, majoritariamente usuários de desktop, sem operadoras móveis.', 1068 'universal default, suitable for most news and information sites.' => 'valor padrão universal, adequado para a maioria dos sites de notícias e informação.', 1069 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'grande parcela de tráfego de operadoras móveis (CGNAT) ou redes corporativas.', 1070 'Important:' => 'Importante:', 1071 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => 'o valor acima se aplica a navegadores normais com User-Agent moderno (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). Para User-Agents vazios ou quebrados, IPs de datacenter, navegadores antigos e bots conhecidos, o limite é aplicado automaticamente 3–6× mais rigoroso.', 1072 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT):', 1073 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'operadoras móveis (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) e redes corporativas atribuem um IP público a centenas de assinantes. Um limite muito baixo bloqueará leitores reais, não atacantes.', 1055 1074 ); -
cyberpulse/trunk/languages/cyberpulse-ru_RU.php
r3763154 r3764759 832 832 'Automatically added administrator IP' => 'Автоматически добавлен IP администратора', 833 833 'No manual entries yet.' => 'Ручных записей пока нет.', 834 'Static file via bot UA' => 'Статический файл запрошен ботом (по User-Agent)', 834 835 835 836 // ------------------------------------------------------------------ … … 1107 1108 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' 1108 1109 => 'Добавляет правила блокировки прямо в .htaccess (только Apache / LiteSpeed). Блокирует ИИ-ботов и чувствительные файлы (.git, .env, .sql, ключи, бэкапы) ещё до загрузки PHP, экономя ресурсы сервера. Правила для ИИ-ботов подчиняются двум переключателям выше — отключение категории убирает её и из .htaccess.', 1110 1111 // Force HTTPS 1112 'Force HTTPS' => 'Принудительный HTTPS', 1113 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => 'Автоматически перенаправляет все HTTP-запросы на HTTPS (301 редирект).', 1114 'Enable only if you have an SSL certificate configured' => 'Включайте только при наличии настроенного SSL-сертификата', 1115 'otherwise the site will become inaccessible.' => 'иначе сайт станет недоступен.', 1116 'Redirect HTTP → HTTPS' => 'Редирект HTTP → HTTPS', 1117 1118 // Flood and DDoS Protection — Help Block 1119 'Recommended: enabled, 40 requests per 60 seconds.' => 'Рекомендуется: включено, 40 запросов за 60 секунд.', 1120 'How to choose the right value' => 'Как выбрать правильное значение', 1121 'homogeneous audience, mostly desktop users, without mobile carriers.' => 'однородная аудитория, преимущественно десктопные пользователи, без мобильных операторов.', 1122 'universal default, suitable for most news and information sites.' => 'универсальное значение по умолчанию, подходит для большинства новостных и информационных сайтов.', 1123 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => 'большая доля трафика с мобильных операторов (CGNAT) или из корпоративных сетей.', 1124 'Important:' => 'Важно:', 1125 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => 'значение из поля выше применяется к обычным браузерам с современным User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). Для пустых или битых User-Agent, IP из дата-центров, старых браузеров и известных ботов лимит автоматически снижается в 3–6 раз.', 1126 'CGNAT (Carrier-Grade NAT):' => 'CGNAT (Carrier-Grade NAT):', 1127 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => 'мобильные операторы (МТС, МегаФон, Билайн, Airtel, Claro, Jio, Vivo) и корпоративные сети выдают один публичный IP сотням абонентов. Слишком низкий лимит заблокирует реальных читателей, а не атакующих.', 1109 1128 ); -
cyberpulse/trunk/languages/cyberpulse-zh_CN.php
r3763154 r3764759 824 824 'Enable ONLY if' => '仅在以下情况下启用', 825 825 'you use Cloudflare (orange cloud enabled in DNS).' => '您使用Cloudflare(DNS中启用橙色云)。', 826 'Static file via bot UA' => '通过机器人 User-Agent 访问静态文件', 826 827 827 828 // ------------------------------------------------------------------ … … 1053 1054 'Applied automatically on save. Rules removed when unchecked. Other .htaccess content (WordPress, caching plugins, etc.) is preserved. A failed write is verified and rolled back automatically.' => '保存时自动应用。取消勾选时删除规则。保留 .htaccess 的其他内容(如 WordPress、缓存插件等)。写入失败时会自动验证并回滚。', 1054 1055 'Adds blocking rules directly to .htaccess (Apache / LiteSpeed only). Blocks AI bots and sensitive files (.git, .env, .sql, keys, backups) before PHP even loads, saving server resources. The AI-bot rules follow the two toggles above — disabling a category also removes it from .htaccess.' => '直接将拦截规则添加到 .htaccess(仅限 Apache / LiteSpeed)。在加载 PHP 之前拦截 AI 机器人和敏感文件(.git、.env、.sql、密钥、备份),节省服务器资源。AI 机器人规则遵循上方的两个开关——禁用某个类别也会将其从 .htaccess 中移除。', 1056 1057 // Force HTTPS 1058 'Force HTTPS' => '强制 HTTPS', 1059 'Automatically redirects all HTTP requests to HTTPS (301 redirect).' => '自动将所有 HTTP 请求重定向到 HTTPS(301 重定向)。', 1060 'Enable only if you have an SSL certificate configured' => '仅当您已配置 SSL 证书时才启用', 1061 'otherwise the site will become inaccessible.' => '否则网站将无法访问。', 1062 'Redirect HTTP → HTTPS' => '重定向 HTTP → HTTPS', 1063 1064 // Flood and DDoS Protection — Help Block 1065 'Recommended: enabled, 40 requests per 60 seconds.' => '推荐:开启,每 60 秒 40 次请求。', 1066 'How to choose the right value' => '如何选择正确的值', 1067 'homogeneous audience, mostly desktop users, without mobile carriers.' => '受众单一,以桌面用户为主,无移动运营商。', 1068 'universal default, suitable for most news and information sites.' => '通用默认值,适合大多数新闻和信息网站。', 1069 'large share of mobile-carrier traffic (CGNAT) or corporate networks.' => '移动运营商(CGNAT)或企业网络流量占比较大。', 1070 'Important:' => '重要提示:', 1071 'the value above applies to normal browsers with a modern User-Agent (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+). For empty or broken User-Agents, datacenter IPs, old browsers, and known bots the limit is applied 3–6× stricter automatically.' => '上述值适用于使用现代 User-Agent(Chrome 90+、Firefox 90+、Safari 14+、Edge 90+)的正常浏览器。对于空或损坏的 User-Agent、数据中心 IP、旧浏览器和已知机器人,限制会自动收紧 3–6 倍。', 1072 'CGNAT (Carrier-Grade NAT):' => 'CGNAT(运营商级 NAT):', 1073 'mobile carriers (MTS, MegaFon, Beeline, Airtel, Claro, Jio, Vivo) and corporate networks assign one public IP to hundreds of subscribers. A too-low limit will block real readers, not attackers.' => '移动运营商(MTS、MegaFon、Beeline、Airtel、Claro、Jio、Vivo)和企业网络为一个公网 IP 分配数百个用户。限制过低会阻止真实读者,而非攻击者。', 1055 1074 ); -
cyberpulse/trunk/readme.txt
r3763154 r3764759 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 5.9.1. 27 Stable tag: 5.9.1.3 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 31 31 * 🤖 AI Scraping Protection — blocks GPTBot, ClaudeBot, PerplexityBot, CCBot, and other AI data collectors 32 32 * 🛡️ Server-level `.htaccess` protection — optional (opt-in) blocking of sensitive files and AI bots directly at the Apache/LiteSpeed level 33 * 🔍 Multi-layer bot detection ( 11 independent checks: User-Agent, HTTP headers, Referer, Accept-Language, and more)33 * 🔍 Multi-layer bot detection (20+ independent checks: User-Agent, HTTP headers, Referer, Accept-Language, behavioral analysis, and more) 34 34 * 🔐 Brute force protection — automatic permanent /24 subnet ban after exceeding attempt limit 35 35 * 🌍 IP Management — block IPs, subnets (/24), whitelist trusted addresses, detect visitor country by IP … … 37 37 * ⏱️ Rate Limiting — configurable request limits to prevent DDoS and aggressive scraping 38 38 * ✅ IP Whitelist — manual and automatic (server IP, search engines, administrator IPs) 39 * 🔒 Force HTTPS redirect — automatic 301 redirect from HTTP to HTTPS with proxy-loop protection 39 40 * 🛡️ XSS attack protection — blocks cross-site scripting in requests 40 41 * 🔎 404 scanner detection — blocks vulnerability scanners by excessive 404 errors … … 67 68 = 🔍 How does bot detection work? = 68 69 69 CyberPulse analyzes 11 parameters of every request: User-Agent, HTTP headers, Accept-Language, Referer, browser headers (Sec-Fetch-*), and more. Suspicious requests are blocked automatically with temporary or permanent IP bans.70 CyberPulse analyzes 20+ parameters of every request: User-Agent, HTTP headers, Accept-Language, Referer, browser headers (Sec-Fetch-*), behavioral patterns, and more. Suspicious requests are blocked automatically with temporary or permanent IP bans. 70 71 71 72 = ⚡ Does it slow down my site? = … … 108 109 4. 📁 Page tracking and traffic analytics 109 110 5. ✅ Whitelist management panel 110 6. ⚙️ Security settings with 11bot detection options111 6. ⚙️ Security settings with multiple bot detection options 111 112 112 113 == Changelog == 114 115 = 5.9.1.3 = 116 * ⚡ Performance: Lowered the default Rate Limiting threshold from 60 to 40 requests per minute. Added a smart collapsible guide in the UI to help users choose the right value (with CGNAT and mobile carrier warnings). 117 * 🛡️ Custom Static 403 Page: When .htaccess protection blocks a bot, it now displays a beautifully styled cyberpulse-403.html page instead of the hosting provider's default error page. 118 * 🔧 Better UX: Replaced the "Back to Home" button with a "Refresh Page" button on the static block page, which is more useful for temporary blocks. 119 * 🔒 New Free Feature: Force HTTPS 301 redirect with proxy-loop protection, full-width UI, and translations for all 10 supported languages. 113 120 114 121 = 5.9.1.2 = … … 275 282 == Source Code == 276 283 277 The original unminified developer source code is available at: 278 https://github.com/gataurus/cyberpulse 284 The original unminified developer source code is available inside the plugin package (in the .zip archive) or via the WordPress.org SVN repository.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)