Changeset 3289923
- Timestamp:
- 05/08/2025 02:09:01 PM (8 months ago)
- Location:
- fortress-login-pro/trunk
- Files:
-
- 6 edited
-
fortress-login-pro.php (modified) (2 diffs)
-
includes/filters-hooks.php (modified) (11 diffs)
-
readme.txt (modified) (6 diffs)
-
templates/access-denied-page.php (modified) (1 diff)
-
templates/email-template.php (modified) (1 diff)
-
templates/test-email-template.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
fortress-login-pro/trunk/fortress-login-pro.php
r3289880 r3289923 3 3 * Plugin Name: Fortress Login Pro – Secure, Hide & Rename Login URL 4 4 * Description: Secure and rotate your WordPress login slug. Block brute force attacks, track attempts, and auto-rotate slugs via email. 5 * Version: 1.1. 15 * Version: 1.1.2 6 6 * Author: hamdisaidani 7 7 * License: GPL2+ … … 12 12 13 13 // Define plugin constants 14 define('FORTLOPR_VERSION', '1.1. 1');14 define('FORTLOPR_VERSION', '1.1.2'); 15 15 define('FORTLOPR_PLUGIN_DIR', plugin_dir_path(__FILE__)); 16 16 define('FORTLOPR_PLUGIN_URL', plugin_dir_url(__FILE__)); -
fortress-login-pro/trunk/includes/filters-hooks.php
r3289752 r3289923 9 9 // Include the logger to track unauthorized access attempts 10 10 require_once plugin_dir_path(__FILE__) . '/../core/logger.php'; 11 12 // Start session for tracking state if not already started 13 if (!isset($_SESSION) && !headers_sent()) { 14 session_start(); 15 } 16 17 // Emergency flush of rewrite rules to fix password reset URL issues 18 function fortlopr_emergency_flush_rules() { 19 // Only do this once per session to avoid performance issues 20 if (!isset($_SESSION['fortress_emergency_flush_done'])) { 21 // Force flush rewrite rules when we have active custom login slug 22 $active_slug = get_option('fortress_active_slug', 'wp-login.php'); 23 if ($active_slug !== 'wp-login.php') { 24 flush_rewrite_rules(true); 25 // Mark as done for this session 26 $_SESSION['fortress_emergency_flush_done'] = true; 27 } 28 } 29 } 30 // Run emergency flush 31 fortlopr_emergency_flush_rules(); 11 32 12 33 /** … … 462 483 add_action('template_redirect', 'fortlopr_handle_login_template', 5); 463 484 464 // Optional: Redirect wp-login.php to custom slug465 add_action('login_init', 'fortlopr_redirect_wp_login', 5);466 467 485 // Block access to login-like paths 468 486 add_action('template_redirect', 'fortlopr_block_login_like_paths', 4); … … 470 488 } 471 489 add_action('wp', 'fortlopr_init_login_handlers'); 490 491 /** 492 * Add direct hook for wp-login.php redirection 493 * This needs to be outside the normal handlers to catch direct access to wp-login.php 494 */ 495 function fortlopr_setup_login_redirect() { 496 $active_slug = get_option('fortress_active_slug', 'wp-login.php'); 497 498 // Only add redirect if using a custom slug 499 if ($active_slug !== 'wp-login.php') { 500 add_action('login_init', 'fortlopr_redirect_wp_login', 5); 501 } 502 } 503 add_action('init', 'fortlopr_setup_login_redirect', 5); 472 504 473 505 /** … … 497 529 add_rewrite_rule( 498 530 '^' . $slug . '/?$', 531 'index.php?fortress_login=1&fortress_slug_type=active', 532 'top' 533 ); 534 535 // Add rewrite rule for active slug with wp-login.php 536 add_rewrite_rule( 537 '^' . $slug . '/wp-login\.php', 499 538 'index.php?fortress_login=1&fortress_slug_type=active', 500 539 'top' … … 512 551 add_rewrite_rule( 513 552 '^' . $pending_slug . '/?$', 553 'index.php?fortress_login=1&fortress_slug_type=pending', 554 'top' 555 ); 556 557 // Add rewrite rule for pending slug with wp-login.php 558 add_rewrite_rule( 559 '^' . $pending_slug . '/wp-login\.php', 514 560 'index.php?fortress_login=1&fortress_slug_type=pending', 515 561 'top' … … 604 650 // Exit early if not a login request 605 651 if (!get_query_var('fortress_login')) { 652 // Special handling for combined URLs (slug/wp-login.php?checkemail=confirm) 653 $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; 654 $active_slug = get_option('fortress_active_slug', 'wp-login.php'); 655 656 // If this is a checkemail=confirm on a combined path, process it 657 if (strpos($request_uri, trim($active_slug, '/') . '/wp-login.php') === 1 && 658 isset($_GET['checkemail']) && 659 sanitize_text_field(wp_unslash($_GET['checkemail'])) === 'confirm') { 660 661 // Include the login form to handle the reset confirmation 662 include_once(ABSPATH . 'wp-login.php'); 663 exit; 664 } 665 606 666 return; 607 667 } 608 609 global $pagenow, $user_login, $error;610 668 611 669 // Store which slug was used (active or pending) … … 852 910 } 853 911 912 // Allow any wp-login.php path with password reset functionality 913 if (strpos($request_path, 'wp-login.php') !== false) { 914 // Allow password reset confirmation on all paths 915 if (isset($_GET['checkemail']) && sanitize_text_field(wp_unslash($_GET['checkemail'])) === 'confirm') { 916 return; 917 } 918 919 // Allow password reset related actions too 920 if (isset($_GET['action']) && in_array(sanitize_text_field(wp_unslash($_GET['action'])), array('lostpassword', 'rp', 'resetpass'), true)) { 921 return; 922 } 923 } 924 925 // Also skip if this is a combination of custom slug and wp-login.php with allowed params 926 if (strpos($request_path, trim($active_slug, '/') . '/wp-login.php') === 0) { 927 // These checks are redundant with the one above, but kept for compatibility 928 if (isset($_GET['checkemail']) && sanitize_text_field(wp_unslash($_GET['checkemail'])) === 'confirm') { 929 return; 930 } 931 932 if (isset($_GET['action']) && in_array(sanitize_text_field(wp_unslash($_GET['action'])), array('lostpassword', 'rp', 'resetpass'), true)) { 933 return; 934 } 935 } 936 854 937 // Also skip if this is the pending slug path (only if pending status is valid) 855 938 $pending_is_valid = !empty($pending_slug) && ($pending_status === 'pending' || $pending_status === 'confirmed'); … … 912 995 return; 913 996 } 997 998 // Allow password reset related actions 999 if (isset($_GET['action']) && in_array(sanitize_text_field(wp_unslash($_GET['action'])), array('lostpassword', 'rp', 'resetpass'), true)) { 1000 return; 1001 } 1002 1003 // Allow password reset confirmation screen 1004 if (isset($_GET['checkemail']) && sanitize_text_field(wp_unslash($_GET['checkemail'])) === 'confirm') { 1005 return; 1006 } 914 1007 } 915 1008 … … 965 1058 } 966 1059 1060 // Also allow password reset confirmation 1061 if (isset($_GET['checkemail']) && sanitize_text_field(wp_unslash($_GET['checkemail'])) === 'confirm') { 1062 return; 1063 } 1064 967 1065 // Skip if $_SERVER['REQUEST_URI'] contains AJAX or admin actions 968 1066 if (isset($_SERVER['REQUEST_URI'])) { … … 976 1074 $active_slug = get_option('fortress_active_slug', 'wp-login.php'); 977 1075 978 // Only redirectif using custom slug1076 // Only block if using custom slug 979 1077 if ($active_slug !== 'wp-login.php') { 980 // Redirect to custom login URL 981 wp_safe_redirect(home_url($active_slug)); 1078 // Log the unauthorized access attempt 1079 if (!function_exists('fortlopr_log_access_attempt')) { 1080 require_once plugin_dir_path(__FILE__) . '/../core/logger.php'; 1081 } 1082 1083 // Prepare URL for logging 1084 $host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; 1085 $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; 1086 $url_attempted = esc_url_raw('http://' . $host . $request_uri); 1087 1088 // Log the access attempt if it passes our filters 1089 if (fortlopr_should_log_access($url_attempted)) { 1090 fortlopr_log_access_attempt([ 1091 'ip_address' => isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : 'Unknown', 1092 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : 'Unknown', 1093 'referrer' => isset($_SERVER['HTTP_REFERER']) ? esc_url_raw(wp_unslash($_SERVER['HTTP_REFERER'])) : 'Direct', 1094 'url_attempted' => $url_attempted, 1095 'timestamp' => current_time('mysql'), 1096 ]); 1097 } 1098 1099 // Show access denied page instead of redirecting 1100 status_header(403); 1101 include plugin_dir_path(__FILE__) . '/../templates/access-denied-page.php'; 982 1102 exit; 983 1103 } … … 1032 1152 if (strpos($path, 'action=confirm_admin_email') !== false) { 1033 1153 return $url; 1154 } 1155 1156 // Special handling for password reset confirmation 1157 if (strpos($path, 'checkemail=confirm') !== false) { 1158 // Keep the original URL with the custom slug added 1159 return home_url('/' . trim($active_slug, '/') . $path); 1034 1160 } 1035 1161 -
fortress-login-pro/trunk/readme.txt
r3289880 r3289923 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.2 7 Stable tag: 1.1. 17 Stable tag: 1.1.2 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 21 21 ### 🔐 Key Features 22 22 23 - **Custom Login URL:** Hide `wp-login.php` and set your own private login path 24 - **Auto-Rotate Slugs:** Automatically change your login URL on a custom schedule 25 - **Dual-Slug Rotation Safety:** Keep the old URL live until the new one is used (fail-safe) 26 - **Slug Generator:** Choose readable word combos or full-random slugs (with number support) 27 - **Access Logs & Charts:** See IPs, timestamps, referrers, and user-agents by login attempt 28 - **Export Logs:** Download access history or slug changes in CSV or JSON 29 - **Slug History Panel:** Restore, archive, or delete old slugs anytime 30 - **SMTP Configuration:** Set up outgoing email for login slug alerts and rotation notices 31 - **Test Email & Rotation:** Built-in checks before activating rotation so you don’t get locked out 32 - **Clean UI:** Fast, modern dashboard with zero bloat or upsell traps 23 - **Custom Login URL:** Hide `wp-login.php` and set your own private login path 24 - **Auto-Rotate Slugs:** Automatically change your login URL on a custom schedule 25 - **Dual-Slug Rotation Safety:** Keep the old URL live until the new one is used (fail-safe) 26 - **Slug Generator:** Choose readable word combos or full-random slugs (with number support) 27 - **Access Logs & Charts:** See IPs, timestamps, referrers, and user-agents by login attempt 28 - **Export Logs:** Download access history or slug changes in CSV or JSON 29 - **Slug History Panel:** Restore, archive, or delete old slugs anytime 30 - **SMTP Configuration:** Set up outgoing email for login slug alerts and rotation notices 31 - **Test Email & Rotation:** Built-in checks before activating rotation so you don’t get locked out 32 - **Clean UI:** Fast, modern dashboard with zero bloat or upsell traps 33 33 34 34 ### ✅ Works With … … 52 52 == Installation == 53 53 54 1. Upload the plugin to `/wp-content/plugins/` 55 2. Activate via **Plugins → Installed Plugins** 56 3. Go to **Fortress Login Pro** in your dashboard 57 4. Choose a login slug (manual or generated), then click **Save** 58 5. Bookmark or email yourself the new URL — your old login path is now hidden 54 1. Upload the plugin to `/wp-content/plugins/` 55 2. Activate via **Plugins → Installed Plugins** 56 3. Go to **Fortress Login Pro** in your dashboard 57 4. Choose a login slug (manual or generated), then click **Save** 58 5. Bookmark or email yourself the new URL — your old login path is now hidden 59 59 60 60 --- … … 98 98 3. Slug history view with restore/delete options 99 99 4. SMTP configuration and test email panel 100 5. Access Denied page template 100 5. Access Denied page template 101 101 102 102 --- … … 104 104 == Changelog == 105 105 106 = 1.1.2 = 107 * Security Fix: Blocked direct access to wp-login.php when custom slug is active 108 106 109 = 1.1.1 = 107 * Fixed bug where Copy and Generate buttons were incorrectly disabled by SMTP status 108 * Improved empty-state UI for Analytics Overview chart 110 * Fixed bug where Copy and Generate buttons were incorrectly disabled by SMTP status 111 * Improved empty-state UI for Analytics Overview chart 109 112 110 113 = 1.1.0 = 111 * Added dual-slug auto-rotation (fail-safe) 112 * Added slug generator: readable vs random + number toggle 113 * Enhanced UI with slug strength meter, rotation timers, and status badges 114 * Improved SMTP configuration with test email verification 115 * Added slug history metadata (source, usage, status) 114 * Added dual-slug auto-rotation (fail-safe) 115 * Added slug generator: readable vs random + number toggle 116 * Enhanced UI with slug strength meter, rotation timers, and status badges 117 * Improved SMTP configuration with test email verification 118 * Added slug history metadata (source, usage, status) 116 119 117 120 = 1.0.0 = 118 * Initial release 121 * Initial release 119 122 120 123 --- … … 122 125 == Upgrade Notice == 123 126 124 1.1. 1 includes a UI bug fix and a visual enhancement. Recommended for all users.127 1.1.2 includes a critical security fix. It is highly recommended for all users. 125 128 126 129 --- -
fortress-login-pro/trunk/templates/access-denied-page.php
r3289880 r3289923 5 5 * 6 6 * @package FortressLoginPro 7 * @version 1.1. 17 * @version 1.1.2 8 8 */ 9 9 -
fortress-login-pro/trunk/templates/email-template.php
r3289880 r3289923 5 5 * 6 6 * @package FortressLoginPro 7 * @version 1.1. 17 * @version 1.1.2 8 8 */ 9 9 -
fortress-login-pro/trunk/templates/test-email-template.php
r3289880 r3289923 5 5 * 6 6 * @package FortressLoginPro 7 * @version 1.1. 17 * @version 1.1.2 8 8 */ 9 9
Note: See TracChangeset
for help on using the changeset viewer.