PluginProbe
Loginizer / 1.9.2
Loginizer v1.9.2
2.1.0 2.0.9 2.0.8 1.9.8 1.9.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 All 74 releases
loginizer / main / settings / security.php

security.php in Loginizer 1.9.2, at main/settings/security.php

1,007 lines 35.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if(!defined('ABSPATH')){
4 die('Hacking Attempt!');
5 }
6
7 // Loginizer - Security Settings Page
8 function loginizer_page_security(){
9
10 global $loginizer, $lz_error, $lz_env, $wpdb;
11
12 if(!current_user_can('manage_options')){
13 wp_die('Sorry, but you do not have permissions to change settings.');
14 }
15
16 if(!loginizer_is_premium() && count($_POST) > 0){
17 $lz_error['not_in_free'] = __('This feature is not available in the Free version. <a href="'.LOGINIZER_PRICING_URL.'" target="_blank" style="text-decoration:none; color:green;"><b>Upgrade to Pro</b></a>', 'loginizer');
18 return loginizer_page_security_T();
19 }
20
21 /* Make sure post was from this page */
22 if(count($_POST) > 0){
23 check_admin_referer('loginizer-options');
24 }
25
26 if(isset($_POST['save_lz'])){
27
28 $option['login_slug'] = lz_optpost('login_slug');
29 $option['rename_login_secret'] = (int) lz_optpost('rename_login_secret');
30 $option['xmlrpc_slug'] = lz_optpost('xmlrpc_slug');
31 $option['xmlrpc_disable'] = (int) lz_optpost('xmlrpc_disable');
32 $option['pingbacks_disable'] = (int) lz_optpost('pingbacks_disable');
33
34 // Login Slug Valid ?
35 if(!empty($option['login_slug'])){
36 if(strlen($option['login_slug']) <= 4 || strlen($option['login_slug']) > 50){
37 $lz_error['login_slug'] = __('The Login slug length must be greater than <b>4</b> chars and upto <b>50</b> chars long', 'loginizer');
38 }
39 }
40
41 // login slug and admin slug cannot be the same
42 $_loginizer_wp_admin = get_option('loginizer_wp_admin');
43 if(!empty($_loginizer_wp_admin['admin_slug']) && $_loginizer_wp_admin['admin_slug'] == $option['login_slug']){
44 $lz_error['lz_same_slug'] = __('The wp-login.php and wp-admin slugs cannot be the same. Choose unique names for login and admin slugs', 'loginizer');
45 return loginizer_page_security_T();
46 }
47
48 // XML-RPC Slug Valid ?
49 if(!empty($option['xmlrpc_slug'])){
50 if(strlen($option['xmlrpc_slug']) <= 4 || strlen($option['xmlrpc_slug']) > 50){
51 $lz_error['xmlrpc_slug'] = __('The XML-RPC slug length must be greater than <b>4</b> chars and upto <b>50</b> chars long', 'loginizer');
52 }
53 }
54
55 // Is there an error ?
56 if(!empty($lz_error)){
57 return loginizer_page_security_T();
58 }
59
60 // Save the options
61 update_option('loginizer_security', $option);
62
63 // Mark as saved
64 $GLOBALS['lz_saved'] = true;
65
66 }
67
68 // Reset the username
69 if(isset($_POST['save_lz_admin'])){
70
71 // Get the new username
72 $current_username = lz_optpost('current_username');
73 $new_username = lz_optpost('new_username');
74
75 if(empty($current_username)){
76 $lz_error['current_username_empty'] = __('Current username is required', 'loginizer');
77 return loginizer_page_security_T();
78 }
79
80 if(empty($new_username)){
81 $lz_error['new_username_empty'] = __('New username is required', 'loginizer');
82 return loginizer_page_security_T();
83 }
84
85 // Is the starting of the username having 'admin' ?
86 if(@strtolower(substr($new_username, 0, 5)) == 'admin'){
87 $lz_error['user_exists'] = __('The username begins with <b>admin</b>. Please change it !', 'loginizer');
88 return loginizer_page_security_T();
89 }
90
91 // Lets check if there is such a user
92 $found = get_user_by('login', $new_username);
93
94 // Found one !
95 if(!empty($found->ID)){
96 $lz_error['user_exists'] = __('The new username is already assigned to another user', 'loginizer');
97 return loginizer_page_security_T();
98 }
99
100 $old_user = get_user_by('login', $current_username);
101
102 if(empty($old_user->ID)){
103 $lz_error['current_username_invalid'] = __('No user found with the current username provided', 'loginizer');
104 return loginizer_page_security_T();
105 }
106
107 if(empty($old_user->caps['administrator'])){
108 $lz_error['user_not_admin'] = __('The user is not an administrator. Only administrator user\'s username can be changed.', 'loginizer');
109 return loginizer_page_security_T();
110 }
111
112 $is_super_admin = 0;
113 if(is_multisite() && is_super_admin($old_user->ID)){
114 $is_super_admin = 1;
115 }
116
117 // Update the username
118 $update_data = array('user_login' => $new_username);
119 $where_data = array('ID' => $old_user->ID);
120
121 $format = array('%s');
122 $where_format = array('%d');
123
124 $wpdb->update($wpdb->prefix.'users', $update_data, $where_data, $format, $where_format);
125
126 // Update the super admins list for multisite
127 if(!empty($is_super_admin)){
128
129 $super_admins = get_site_option('site_admins');
130
131 foreach($super_admins as $sk => $sv){
132 // Remove the existing username from super admins list
133 if($sv == $current_username){
134 unset($super_admins[$sk]);
135 }
136 }
137
138 // Add the new username
139 $super_admins[] = $new_username;
140
141 update_site_option( 'site_admins', $super_admins );
142
143 }
144
145 // Mark as saved
146 $GLOBALS['lz_saved'] = true;
147
148 }
149
150 // Change the wp-admin slug
151 if(isset($_POST['save_lz_wp_admin'])){
152
153 // Get the new username
154 $option['admin_slug'] = lz_optpost('admin_slug');
155 $option['restrict_wp_admin'] = (int) lz_optpost('restrict_wp_admin');
156 $option['wp_admin_msg'] = @stripslashes($_POST['wp_admin_msg']);
157 $lz_wp_admin_docs = (int) lz_optpost('lz_wp_admin_docs');
158
159 // login slug and admin slug cannot be the same
160 $_loginizer_security = get_option('loginizer_security');
161 if(!empty($_loginizer_security['login_slug']) && $_loginizer_security['login_slug'] == $option['admin_slug']){
162 $lz_error['lz_same_slug'] = __('The wp-login.php and wp-admin slugs cannot be the same. Choose unique names for login and admin slugs', 'loginizer');
163 return loginizer_page_security_T();
164 }
165
166 // Did you agree to this ?
167 if(!empty($option['admin_slug']) && empty($lz_wp_admin_docs)){
168 $lz_error['lz_wp_admin_docs'] = __('You have not confirmed that you have read the guide and configured .htaccess. Please read the guide, configure .htaccess and then save these settings and check this checkbox', 'loginizer');
169 return loginizer_page_security_T();
170 }
171
172 // Length
173 if(!empty($option['admin_slug']) && (strlen($option['admin_slug']) <= 4 || strlen($option['admin_slug']) > 50)){
174 $lz_error['admin_slug'] = __('The new Admin slug length must be greater than <b>4</b> chars and upto <b>50</b> chars long', 'loginizer');
175 return loginizer_page_security_T();
176 }
177
178 // Only regular characters
179 if(preg_match('/[^\w\d\-_]/is', $option['admin_slug'])){
180 $lz_error['admin_slug_chars'] = __('Special characters are not allowed', 'loginizer');
181 return loginizer_page_security_T();
182 }
183
184 // Update the option
185 update_option('loginizer_wp_admin', $option);
186
187 // Mark as saved
188 $GLOBALS['lz_saved'] = true;
189
190 }
191
192
193 // Save blacklisted usernames
194 if(isset($_POST['save_lz_bl_users'])){
195
196 $usernames = isset($_POST['lz_bl_users']) && is_array($_POST['lz_bl_users']) ? $_POST['lz_bl_users'] : array();
197
198 // Process the usernames i.e. remove blanks
199 foreach($usernames as $k => $v){
200 $v = trim($v);
201
202 // Unset blank values
203 if(empty($v)){
204 unset($usernames[$k]);
205 }
206
207 // Disallow these special characters to avoid XSS or any other security vulnerability
208 if(preg_match('/[\<\>\"\']/', $v)){
209 unset($usernames[$k]);
210 }
211 }
212
213 // Update the blacklist
214 update_option('loginizer_username_blacklist', array_values($usernames));
215
216 // Mark as saved
217 $GLOBALS['lz_saved'] = true;
218
219 }
220
221
222 // Save blacklisted domains
223 if(isset($_POST['save_lz_bl_domains'])){
224
225 $domains = isset($_POST['lz_bl_domains']) && is_array($_POST['lz_bl_domains']) ? $_POST['lz_bl_domains'] : array();
226
227 // Process the domains i.e. remove blanks
228 foreach($domains as $k => $v){
229 $v = trim($v);
230
231 // Unset blank values
232 if(empty($v)){
233 unset($domains[$k]);
234 }
235
236 // Disallow these special characters to avoid XSS or any other security vulnerability
237 if(preg_match('/[\<\>\"\']/', $v)){
238 unset($domains[$k]);
239 }
240 }
241
242 // Update the blacklist
243 update_option('loginizer_domains_blacklist', array_values($domains));
244
245 // Mark as saved
246 $GLOBALS['lz_saved'] = true;
247
248 }
249
250
251 if(isset($_POST['save_lz_csrf_protection'])){
252 update_option('loginizer_csrf_protection', empty(lz_optpost('enable_csrf_protection')) ? false : true);
253
254 delete_transient('loginizer_csrf_mod_rewrite');
255 $GLOBALS['lz_saved'] = true;
256 }
257
258 if(isset($_POST['save_lz_limit_session'])){
259 $limit_session = map_deep($_POST['limit_session'], 'sanitize_text_field');
260
261 if(empty($limit_session)){
262 delete_option('loginizer_limit_session');
263 } else {
264 update_option('loginizer_limit_session', $limit_session);
265 }
266
267 $GLOBALS['lz_saved'] = true;
268 }
269
270 // Call theme
271 loginizer_page_security_T();
272
273 }
274
275 // Loginizer - Security Settings Page Theme
276 function loginizer_page_security_T(){
277
278 global $loginizer, $lz_error, $lz_env;
279
280 // Universal header
281 loginizer_page_header('Security Settings');
282
283 loginizer_feature_available('Security Settings');
284
285 // Saved ?
286 if(!empty($GLOBALS['lz_saved'])){
287 echo '<div id="message" class="updated"><p>'. __('The settings were saved successfully', 'loginizer'). '</p></div><br />';
288 }
289
290 // Any errors ?
291 if(!empty($lz_error)){
292 lz_report_error($lz_error);echo '<br />';
293 }
294
295 $current_admin = get_user_by('id', 1);
296
297 ?>
298
299 <style>
300 input[type="text"], textarea, select {
301 width: 70%;
302 }
303
304 .form-table label{
305 font-weight:bold;
306 }
307
308 .exp{
309 font-size:12px;
310 }
311 </style>
312
313 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
314
315 <div id="" class="postbox">
316
317 <div class="postbox-header">
318 <h2 class="hndle ui-sortable-handle">
319 <span><?php echo __('Rename Login Page', 'loginizer'); ?></span>
320 </h2>
321 </div>
322
323 <div class="inside">
324
325 <?php wp_nonce_field('loginizer-options'); ?>
326 <table class="form-table">
327 <tr>
328 <td scope="row" valign="top" colspan="2">
329 <i><?php echo __('You can rename your Login page from','loginizer'). ' <b> '. $loginizer['login_basename'].' </b> '.__(' to anything of your choice e.g. mylogin. This would make it very difficult for automated attack bots to know where to login !','loginizer'); ?></i>
330 </td>
331 </tr>
332 <tr>
333 <td scope="row" valign="top" style="width:40% !important">
334 <label><?php echo __('New Login Slug', 'loginizer'); ?></label><br>
335 <span class="exp"><?php echo __('Set blank to reset to the original login URL', 'loginizer'); ?></span>
336 </td>
337 <td>
338 <input type="text" size="50" value="<?php echo (!empty($loginizer['login_slug']) ? lz_POSTval('login_slug', $loginizer['login_slug']) : ''); ?>" name="login_slug" />
339 </td>
340 </tr>
341
342 <?php
343
344 if(!defined('SITEPAD')){
345
346 ?>
347 <tr>
348 <td scope="row" valign="top" style="width:200px !important">
349 <label><?php echo __('Access Secretly Only', 'loginizer'); ?></label><br>
350 <span class="exp"><?php echo __('If set, then all Login URL\'s will still point to '.$loginizer['login_basename'].' and users will have to access the New Login Slug by typing it in the browser.', 'loginizer'); ?></span>
351 </td>
352 <td>
353 <input type="checkbox" value="1" name="rename_login_secret" <?php echo lz_POSTchecked('rename_login_secret', (empty($loginizer['rename_login_secret']) ? false : true)); ?> />
354 </td>
355 </tr>
356
357 <?php
358
359 }
360
361 ?>
362 </table><br />
363 <center><input name="save_lz" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
364
365 </div>
366 </div>
367
368 <?php
369
370 if(!defined('SITEPAD')){
371
372 ?>
373
374 <div id="" class="postbox">
375
376 <div class="postbox-header">
377 <h2 class="hndle ui-sortable-handle">
378 <span><?php echo __('XML-RPC Settings', 'loginizer'); ?></span>
379 </h2>
380 </div>
381
382 <div class="inside">
383
384 <?php wp_nonce_field('loginizer-options'); ?>
385 <table class="form-table">
386 <tr>
387 <td scope="row" valign="top" colspan="2">
388 <i><?php echo __('WordPress\'s XML-RPC feature allows external services to access and modify content on the site. Services like the Jetpack plugin, the WordPress mobile app, pingbacks, etc make use of the XML-RPC feature. If this site does not use a service that requires XML-RPC, please <b>disable</b> the XML-RPC feature as it prevents attackers from using the feature to attack the site. If your service can use a custom XML-RPC URL, you can also <b>rename</b> the XML-RPC page to a <b>custom slug</b>.', 'loginizer'); ?></i>
389 </td>
390 </tr>
391 <tr>
392 <td scope="row" valign="top" style="width:40% !important">
393 <label><?php echo __('Disable XML-RPC', 'loginizer'); ?></label>
394 </td>
395 <td>
396 <input type="checkbox" value="1" name="xmlrpc_disable" <?php echo lz_POSTchecked('xmlrpc_disable', (empty($loginizer['xmlrpc_disable']) ? false : true)); ?> />
397 </td>
398 </tr>
399 <tr>
400 <td scope="row" valign="top" style="width:40% !important">
401 <label><?php echo __('Disable Pingbacks', 'loginizer'); ?></label>
402 </td>
403 <td>
404 <input type="checkbox" value="1" name="pingbacks_disable" <?php echo lz_POSTchecked('pingbacks_disable', (empty($loginizer['pingbacks_disable']) ? false : true)); ?> />
405 </td>
406 </tr>
407 <tr>
408 <td scope="row" valign="top">
409 <label><?php echo __('New XML-RPC Slug', 'loginizer'); ?></label><br>
410 <span class="exp"><?php echo __('Set blank to reset to the original XML-RPC URL', 'loginizer'); ?></span>
411 </td>
412 <td>
413 <input type="text" size="50" value="<?php echo (!empty($loginizer['xmlrpc_slug']) ? lz_optpost('xmlrpc_slug', $loginizer['xmlrpc_slug']) : ''); ?>" name="xmlrpc_slug" />
414 </td>
415 </tr>
416 </table><br />
417 <center><input name="save_lz" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
418
419 </div>
420 </div>
421
422 <?php
423
424 }
425
426 ?>
427
428 </form>
429
430 <?php
431
432 if(!defined('SITEPAD')){
433
434 ?>
435
436 <script type="text/javascript">
437
438 function lz_update_htaccess_admin(e){
439
440 var admin_name = jQuery(e).val();
441
442 if(admin_name.length == 0){
443 admin_name = 'wp-admin';
444 }
445
446 var textarea = jQuery('.lz-htaccess-textarea');
447
448 if(textarea.length == 0) {
449 return;
450 }
451
452 var htaccess = textarea.val();
453 htaccess = htaccess.replace(/\^.+?\(/, '^' + admin_name + '(');
454 textarea.val(htaccess);
455
456 }
457
458
459 function dirname(path) {
460 return path.replace(/\\/g, '/').replace(/\/[^/]*\/?$/, '');
461 }
462
463 function lz_test_wp_admin(){
464
465 var data = new Object();
466 data["action"] = "loginizer_wp_admin";
467 data["nonce"] = "<?php echo wp_create_nonce('loginizer_admin_ajax');?>";
468
469 var new_ajaxurl = dirname(dirname(ajaxurl))+'/'+jQuery('#lz_admin_slug').val()+'/admin-ajax.php';
470
471 // AJAX and on success function
472 jQuery.post(new_ajaxurl, data, function(response){
473
474 if(response['result'] == 1){
475 alert("<?php echo __('Everything seems to be good. You can proceed to save the settings !', 'loginizer'); ?>");
476 }
477
478 // Throw an error for failures
479 }).fail(function() {
480 alert("<?php echo __('There was an error connecting to WordPress with the new Admin Slug. Did you configure everything properly ?', 'loginizer'); ?>");
481 });
482 //jQuery.ajax('<input type="text" size="30" value="" name="lz_bl_users[]" class="lz_bl_users" />');
483 return false;
484 };
485
486 </script>
487
488 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
489 <div id="" class="postbox">
490
491 <div class="postbox-header">
492 <h2 class="hndle ui-sortable-handle">
493 <span><?php echo __('Rename wp-admin access', 'loginizer'); ?></span>
494 </h2>
495 </div>
496
497 <div class="inside">
498
499 <?php wp_nonce_field('loginizer-options'); ?>
500 <table class="form-table">
501 <?php
502 if(preg_match('/(apache|litespeed|lsws)/is', $_SERVER["SERVER_SOFTWARE"])){
503 // Supported. Do nothing
504 }else{
505 echo '<tr>
506 <td scope="row" valign="top" colspan="2">
507 <div style="color:#a94442; background-color:#f2dede; border-color:#ebccd1; padding:15px; border:1px solid transparent; border-radius:4px;">'.__('Rename wp-admin access feature is supported only on Apache and Litespeed', 'loginizer').'</div>
508 </td>
509 </tr>';
510 }
511
512 if(defined('LOGINIZER_PREMIUM') && !empty($loginizer['enable_csrf_protection']) && empty($loginizer['admin_slug'])){
513
514 echo '<div style="color: #856404; background-color: #fff3cd; border-color: #ffeeba; padding: 15px; font-size:1rem; font-weight:400;">'.esc_html__('Note: Be careful while changing the Admin name as your CSRF Protection is on', 'loginizer').'</div>';
515
516 }
517 ?>
518 <tr>
519 <td scope="row" valign="top" colspan="2">
520 <i><?php echo __('You can rename your WordPress Admin access URL <b>wp-admin</b> to anything of your choice e.g. my-admin. This will require you to change .htaccess, so please follow','loginizer'); ?> <a href="<?php echo LOGINIZER_DOCS;?>Renaming_the_WP-Admin_Area" target="_blank"><?php echo __('our guide','loginizer').'</a> '.__('on how to do so !','loginizer'); ?></i>
521 </td>
522 </tr>
523 <tr>
524 <td scope="row" valign="top" style="width:40% !important">
525 <label><?php echo __('New wp-admin Slug', 'loginizer'); ?></label><br>
526 <span class="exp"><?php echo __('Set blank to reset to the original wp-admin URL', 'loginizer'); ?></span>
527 </td>
528 <td>
529 <input type="text" size="50" value="<?php echo (!empty($loginizer['admin_slug']) ? lz_optpost('admin_slug', $loginizer['admin_slug']) : ''); ?>" name="admin_slug" id="lz_admin_slug" onchange="lz_update_htaccess_admin(this)"/>
530 </td>
531 </tr>
532 <tr>
533 <td scope="row" valign="top" style="width:200px !important">
534 <label><?php echo __('Disable wp-admin access', 'loginizer'); ?></label><br>
535 <span class="exp"><?php echo __('If set, then only the new admin slug will work and access to the Old Admin Slug i.e. wp-admin will be disabled. If anyone accesses wp-admin, a warning will be shown.<br><label>NOTE: Please use this option cautiously !</label>', 'loginizer'); ?></span>
536 </td>
537 <td>
538 <input type="checkbox" id="lz_restrict_wp_admin" onchange="lz_wp_admin_msg_toggle()" value="1" name="restrict_wp_admin" <?php echo lz_POSTchecked('restrict_wp_admin', (empty($loginizer['restrict_wp_admin']) ? false : true)); ?> />
539 </td>
540 </tr>
541 <tr id="lz_wp_admin_msg_row" style="display:none">
542 <td scope="row" valign="top">
543 <label><?php echo __('WP-Admin Error Message', 'loginizer'); ?></label><br>
544 <span class="exp"><?php echo __('Error message to show if someone accesses wp-admin', 'loginizer'); ?></span> Default : <?php echo (!empty($loginizer['wp_admin_d_msg']) ? $loginizer['wp_admin_d_msg'] : ''); ?>
545 </td>
546 <td>
547 <input type="text" size="50" value="<?php echo lz_htmlizer(!empty($_POST['wp_admin_msg']) ? stripslashes($_POST['wp_admin_msg']) : (!empty($loginizer['wp_admin_msg']) ? $loginizer['wp_admin_msg'] : '')); ?>" name="wp_admin_msg" id="lz_wp_admin_msg" />
548 </td>
549 </tr>
550
551 <?php
552 loginizer_htaccess_rules();
553 ?>
554 <tr>
555 <td scope="row" valign="top" style="width:200px !important">
556 <label><?php echo __('I have setup .htaccess', 'loginizer'); ?></label><br>
557 <span class="exp"><?php echo __('You need to confirm that you have configured .htaccess as per <a href="'.LOGINIZER_DOCS.'Renaming_the_WP-Admin_Area" target="_blank">our guide</a> so that we can safely enable this feature', 'loginizer'); ?></span>
558 </td>
559 <td>
560 <input type="checkbox" value="1" name="lz_wp_admin_docs" />
561 <input type="button" onclick="lz_test_wp_admin()" class="button" style="background: #5cb85c; color:white; border:#5cb85c" value="<?php echo __('Test New WP-Admin Slug', 'loginizer'); ?>" />
562 </td>
563 </tr>
564 </table><br />
565 <center><input name="save_lz_wp_admin" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
566
567 </div>
568 </div>
569 </form>
570
571 <script type="text/javascript">
572 function lz_csrf_htaccess_update(e){
573 event.preventDefault();
574
575 var tb = jQuery(e).closest('table'),
576 csrf_enabled = tb.find('[name="enable_csrf_protection"]'),
577 admin_name = tb.find('#lz_admin_slug');
578
579 var data = new Object();
580
581 // Setting admin name if anything is set
582 if(admin_name && admin_name.val()){
583 data['admin_name'] = admin_name.val();
584 }
585
586 if(csrf_enabled){
587 data['csrf'] = true;
588 } else {
589 data['csrf'] = false;
590 }
591
592 data['action'] = 'loginizer_update_csrf_mod';
593 data['nonce'] = '<?php echo wp_create_nonce('loginizer_admin_ajax');?>';
594
595 var new_ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>'
596
597 // AJAX and on success function
598 jQuery.post(new_ajaxurl, data, function(response){
599
600 if(response['success'] == true){
601 alert("<?php esc_html_e('.htaccess has been updated !', 'loginizer'); ?>");
602 }
603
604 // Throw an error for failures
605 }).fail(function() {
606 alert("<?php esc_html_e('Was unable to update the .htaccess file so please update it manually', 'loginizer'); ?>");
607 });
608
609 return false;
610
611 }
612
613 function lz_show_rewrite_rule(e){
614 event.preventDefault();
615 jQuery(e).closest('td').find('textarea').toggle();
616 }
617
618
619 </script>
620
621 <!-- Begin CSRF Protection -->
622 <form action="" method="post" loginizer-premium-only="1">
623 <div id="" class="postbox">
624
625 <div class="postbox-header">
626 <h2 class="hndle ui-sortable-handle">
627 <span><?php esc_html_e('CSRF Protection', 'loginizer'); ?></span>
628 </h2>
629 </div>
630
631 <div class="inside">
632
633 <?php wp_nonce_field('loginizer-options'); ?>
634 <table class="form-table">
635 <tr>
636 <td scope="row" valign="top" colspan="2">
637 <i><?php esc_html_e('This helps in preventing CSRF attacks as it updates the admin URLS with a session string which make it difficult and nearly impossible for the attacker to predict the URL', 'loginizer'); ?></i>
638 </td>
639 </tr>
640 <tr>
641 <td scope="row" valign="top" style="width:400px !important">
642 <label><?php esc_html_e('Enable CSRF Protection', 'loginizer'); ?></label><br>
643 <span class="exp"><?php esc_html_e('If enabled, it will update the URL of wp-admin with a random session string in the URL making it hard to predict the URL.', 'loginizer'); ?></span>
644 </td>
645 <td valign="top">
646 <input type="checkbox" value="1" name="enable_csrf_protection" <?php echo lz_POSTchecked('enable_csrf_protection', (empty($loginizer['enable_csrf_protection']) ? false : true)); ?> />
647 </td>
648 </tr>
649 <?php
650 loginizer_htaccess_rules(true);
651 ?>
652 </table><br />
653 <div style="text-align: center;"><input name="save_lz_csrf_protection" class="button button-primary action" value="<?php esc_html_e('Save Settings', 'loginizer'); ?>" type="submit" />
654 </div>
655 </div>
656 </div>
657 </form>
658 <!-- End CSRF Protection -->
659
660
661 <script type="text/javascript">
662
663 function lz_wp_admin_msg_toggle(){
664 var ele = jQuery('#lz_restrict_wp_admin')[0];
665 if(ele.checked){
666 jQuery('#lz_wp_admin_msg_row').show();
667 }else{
668 jQuery('#lz_wp_admin_msg_row').hide();
669 }
670 };
671
672 lz_wp_admin_msg_toggle();
673
674 </script>
675
676
677 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
678 <div id="" class="postbox">
679
680 <div class="postbox-header">
681 <h2 class="hndle ui-sortable-handle">
682 <span><?php echo __('Change Admin Username', 'loginizer'); ?></span>
683 </h2>
684 </div>
685
686 <div class="inside">
687
688 <?php wp_nonce_field('loginizer-options'); ?>
689 <table class="form-table">
690 <tr>
691 <td scope="row" valign="top" colspan="2">
692 <i><?php echo __('You can change the Admin Username from here to anything of your choice e.g. iamtheboss. This would make it very difficult for automated attack bots to know what is the admin username !', 'loginizer'); ?></i>
693 </td>
694 </tr>
695 <tr>
696 <td scope="row" valign="top" style="width:40% !important">
697 <label for="current_username"><?php echo __('Current Username', 'loginizer'); ?></label><br>
698 <span class="exp"><?php echo __('The current username you want to change', 'loginizer'); ?></span>
699 </td>
700 <td>
701 <input type="text" size="50" value="<?php echo lz_optpost('current_username', (!empty($current_admin->user_login) ? $current_admin->user_login : '')); ?>" name="current_username" id="current_username" />
702 </td>
703 </tr>
704 <tr>
705 <td scope="row" valign="top" style="width:40% !important">
706 <label for="new_username"><?php echo __('New Username', 'loginizer'); ?></label><br>
707 <span class="exp"><?php echo __('The new username you want to set', 'loginizer'); ?></span>
708 </td>
709 <td>
710 <input type="text" size="50" value="<?php echo lz_optpost('new_username', ''); ?>" name="new_username" id="new_username" />
711 </td>
712 </tr>
713 </table><br />
714 <i><?php echo __('Note: Username can be changed only for administrator users.'); ?></i>
715 <center><input name="save_lz_admin" class="button button-primary action" value="<?php echo __('Set the Username', 'loginizer'); ?>" type="submit" /></center>
716
717 </div>
718 </div>
719 </form>
720
721 <script type="text/javascript">
722 function add_lz_bl_users(){
723 jQuery("#lz_bl_users").append('<input type="text" size="30" value="" name="lz_bl_users[]" class="lz_bl_users" />');
724 return false;
725 };
726 </script>
727
728 <style>
729 .lz_bl_users, .lz_bl_domains{
730 margin-bottom:20px;
731 }
732 </style>
733
734 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
735 <div id="" class="postbox">
736
737 <div class="postbox-header">
738 <h2 class="hndle ui-sortable-handle">
739 <span><?php echo __('Username Auto Blacklist', 'loginizer'); ?></span>
740 </h2>
741 </div>
742
743 <div class="inside">
744
745 <?php wp_nonce_field('loginizer-options'); ?>
746 <table class="form-table">
747 <tr>
748 <td scope="row" valign="top" colspan="2">
749 <i><?php echo __('Attackers generally use common usernames like <b>admin, administrator, or variations of your domain name / business name</b>. You can specify such username here and Loginizer will auto-blacklist the IP Address(s) of clients who try to use such username(s).', 'loginizer'); ?></i>
750 </td>
751 </tr>
752 <tr>
753 <td scope="row" valign="top" style="width:40% !important; vertical-align:top !important;">
754 <label><?php echo __('Username(s)', 'loginizer'); ?></label><br>
755 <span class="exp"><?php echo __('You can use - <b>*</b> (Star)- as a wild card as well. Blank fields will be ignored', 'loginizer'); ?></span>
756 </td>
757 <td>
758 <div id="lz_bl_users">
759 <?php
760
761 $usernames = isset($_POST['lz_bl_users']) && is_array($_POST['lz_bl_users']) ? $_POST['lz_bl_users'] : (!empty($loginizer['username_blacklist']) ? $loginizer['username_blacklist'] : []);
762
763 if(empty($usernames)){
764 $usernames = array();
765 $usernames[] = '';
766 }
767
768 foreach($usernames as $_user){
769
770 // Disallow these special characters to avoid XSS or any other security vulnerability
771 if(preg_match('/[\<\>\"\']/', $_user)){
772 continue;
773 }
774
775 echo '<input type="text" size="30" value="'.$_user.'" name="lz_bl_users[]" class="lz_bl_users" />';
776 }
777
778 ?>
779 </div>
780 <br />
781 <input class="button" type="button" value="<?php echo __('Add New Username', 'loginizer'); ?>" onclick="return add_lz_bl_users();" style="float:right" />
782 </td>
783 </tr>
784 </table><br />
785 <center><input name="save_lz_bl_users" class="button button-primary action" value="<?php echo __('Save Username(s)', 'loginizer'); ?>" type="submit" /></center>
786
787 </div>
788 </div>
789 </form>
790
791 <script type="text/javascript">
792 function add_lz_bl_domains(){
793 jQuery("#lz_bl_domains").append('<input type="text" size="30" value="" name="lz_bl_domains[]" class="lz_bl_domains" />');
794 return false;
795 };
796 </script>
797
798
799 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
800 <div id="" class="postbox">
801
802 <div class="postbox-header">
803 <h2 class="hndle ui-sortable-handle">
804 <span><?php echo __('New Registration Domain Blacklist', 'loginizer'); ?></span>
805 </h2>
806 </div>
807
808 <div class="inside">
809
810 <?php wp_nonce_field('loginizer-options'); ?>
811 <table class="form-table">
812 <tr>
813 <td scope="row" valign="top" colspan="2">
814 <i>If you would like to ban new registrations from a particular domain, you can use this utility to do so.</i>
815 </td>
816 </tr>
817 <tr>
818 <td scope="row" valign="top" style="width:40% !important; vertical-align:top !important;">
819 <label><?php echo __('Domain(s)', 'loginizer'); ?></label><br>
820 <span class="exp"><?php echo __('You can use - <b>*</b> (Star)- as a wild card as well. Blank fields will be ignored', 'loginizer'); ?></span>
821 </td>
822 <td>
823 <div id="lz_bl_domains">
824 <?php
825
826 $domains = isset($_POST['lz_bl_domains']) && is_array($_POST['lz_bl_domains']) ? $_POST['lz_bl_domains'] : (!empty($loginizer['domains_blacklist']) ? $loginizer['domains_blacklist'] : []);
827
828 if(empty($domains)){
829 $domains = array();
830 $domains[] = '';
831 }
832
833 foreach($domains as $_domain){
834
835 // Disallow these special characters to avoid XSS or any other security vulnerability
836 if(preg_match('/[\<\>\"\']/', $_domain)){
837 continue;
838 }
839
840 echo '<input type="text" size="30" value="'.$_domain.'" name="lz_bl_domains[]" class="lz_bl_domains" />';
841 }
842
843 ?>
844 </div>
845 <br />
846 <input class="button" type="button" value="<?php echo __('Add New Domain', 'loginizer'); ?>" onclick="return add_lz_bl_domains();" style="float:right" />
847 </td>
848 </tr>
849 </table><br />
850 <center><input name="save_lz_bl_domains" class="button button-primary action" value="<?php echo __('Save Domains(s)', 'loginizer'); ?>" type="submit" /></center>
851
852 </div>
853 </div>
854 </form>
855
856 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
857 <div id="" class="postbox">
858
859 <div class="postbox-header">
860 <h2 class="hndle ui-sortable-handle">
861 <span><?php echo __('Limit Concurrent Sessions', 'loginizer');
862 if(time() < strtotime('30 July 2023')){
863 echo ' <span style="color:red;">New</span></span>';
864 } ?>
865 </h2>
866 </div>
867
868 <div class="inside">
869
870 <?php wp_nonce_field('loginizer-options'); ?>
871 <table class="form-table">
872 <tr>
873 <td scope="row" valign="top" colspan="2">
874 <i><?php echo __('This feature will help limit the number of devices your user can login to concurrently', 'loginizer'); ?></i>
875 </td>
876 </tr>
877 <tr>
878 <td scope="row" valign="top" style="width:300px !important">
879 <label><?php echo __('Enable', 'loginizer'); ?></label><br>
880 <span class="exp"><?php echo __('Enabling it will start limiting number of devices the user can login on concurrently', 'loginizer'); ?></span>
881 </td>
882 <td>
883 <input type="checkbox" value="1" name="limit_session[enable]" <?php echo (!empty($_POST['limit_session']['enable']) || (!empty($loginizer['limit_session']['enable']))) ? 'checked' : false; ?> />
884 </td>
885 </tr>
886 <tr>
887 <td scope="row" valign="top" style="width:300px !important">
888 <label><?php echo __('Limit Type', 'loginizer'); ?></label><br>
889 </td>
890 <td>
891 <input type="radio" value="block" name="limit_session[type]" <?php echo ((!empty($_POST['limit_session']['type']) && $_POST['limit_session']['type'] == 'block') || (!empty($loginizer['limit_session']['type']) && $loginizer['limit_session']['type'] == 'block' ) ? 'checked' : false); ?> />
892 <span class="exp"><?php echo '<strong>'.__('Block', 'loginizer') . ' : </strong>' . __('Blocks all the login attempts if limit is reached', 'loginizer'); ?></span><br/>
893 <input type="radio" value="destroy" name="limit_session[type]" <?php echo ((!empty($_POST['limit_session']['type']) && $_POST['limit_session']['type'] == 'destroy') || (!empty($loginizer['limit_session']['type']) && $loginizer['limit_session']['type'] == 'destroy' ) ? 'checked' : false); ?> />
894 <span class="exp"><?php echo '<strong>'.__('Destroy', 'loginizer') . ' : </strong>' . __('Revokes all the sessions on successful login', 'loginizer'); ?></span>
895 </td>
896 </tr>
897 <tr>
898 <td scope="row" valign="top" style="width:40% !important">
899 <label><?php echo __('Max Session Count', 'loginizer'); ?></label><br>
900 <span class="exp"><?php echo __('Set Maximum number of sessions can be created', 'loginizer'); ?></span>
901 </td>
902 <td>
903 <input type="number" min="1" max="10" size="20" value="<?php echo (!empty($_POST['limit_session']['count']) ? esc_attr($_POST['limit_session']['count']) : (!empty($loginizer['limit_session']['count']) ? esc_attr($loginizer['limit_session']['count']) : 1)); ?>" name="limit_session[count]" />
904 </td>
905 </tr>
906 <tr>
907 <tr>
908 <td scope="row" valign="top">
909 <label><?php echo __('Exclude Roles', 'loginizer'); ?></label><br>
910 <span class="exp"><?php echo __('Excluded roles won\'t face session limit checks', 'loginizer'); ?></span>
911 </td>
912 <td>
913 <div style="max-height:120px;; overflow-y:auto;">
914 <?php
915 global $wp_roles;
916
917 foreach($wp_roles->roles as $key => $role){
918 $checked = '';
919
920 if(!empty($_POST['limit_session']['roles']) && in_array($key, $_POST['limit_session']['roles'])
921 || !empty($loginizer['limit_session']['roles']) && in_array($key, $loginizer['limit_session']['roles'])){
922 $checked = 'checked';
923 }
924
925
926 echo '<input type="checkbox" value="'.esc_attr($key).'" name="limit_session[roles][]" '.esc_attr($checked).'/>'. esc_html($role['name']) . '<br/>';
927 }
928 ?>
929 </div>
930 </td>
931 </tr>
932 </table><br/>
933 <center><input name="save_lz_limit_session" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
934
935 </div>
936 </div>
937 </form>
938
939 <?php
940
941 }
942
943 loginizer_page_footer();
944
945 }
946
947 // .htaccess UI options for wp-admin and CSRF
948 function loginizer_htaccess_rules($is_csrf = false){
949 global $loginizer;
950
951 $admin_slug = 'wp-admin';
952
953 if(!empty($loginizer['admin_slug'])){
954 $admin_slug = $loginizer['admin_slug'];
955 }
956
957 // getting sub directory if any
958 $home_root = parse_url(home_url());
959
960 if(isset($home_root['path'])){
961 $home_root = trailingslashit($home_root['path']);
962 } else {
963 $home_root = '/';
964 }
965
966 // Selecting admin slug
967 $admin_slug = 'wp-admin';
968
969 if(!empty($loginizer['admin_slug'])){
970 $admin_slug = $loginizer['admin_slug'];
971 }
972
973 // Setting the rule
974 $rule = '# BEGIN Loginizer' . "\n";
975 $rule .= '<IfModule mod_rewrite.c>' . "\n";
976 $rule .= 'RewriteEngine On' . "\n";
977 $rule .= 'RewriteBase ' . $home_root . "\n\n";
978 $rule .= 'RewriteRule ^' . $admin_slug . '(-lzs.{20})?(/?)(.*) wp-admin/$3 [L]' . "\n";
979 $rule .= '</IfModule>' . "\n";
980 $rule .= '# END Loginizer' . "\n";
981
982 if(is_writable(ABSPATH . '/.htaccess')){
983 echo '<tr>
984 <td scope="row" valign="top" style="width:400px !important">
985 <label>'. esc_html__('Update .htaccess', 'loginizer').'</label><br>
986 <span class="exp">'. (!empty($is_csrf) ? esc_html__('Rewrites rule for CSRF session URL', 'loginizer') : esc_html__('Rewrites rule to change wp-admin and if you have a Multisite then check', 'loginizer') . ' <a href="'.LOGINIZER_DOCS.'Renaming_the_WP-Admin_Area" target="_blank">our guide</a>') . '</span>
987 </td>
988 <td valign="top">
989 <button class="button" style="background: #5cb85c; color:white; border:#5cb85c;" onclick="lz_csrf_htaccess_update(this)">Update .htaccess</button><a onClick="lz_show_rewrite_rule(this)" href="#" style="margin-left:5px; line-height: 2; font-weight:500;">Show Rewrite Rule</a><br/><br/>
990
991 <textarea rows="8" readonly style="display:none;" class="lz-htaccess-textarea">' . trim($rule) . '</textarea>
992 </td>
993 </tr>';
994
995 } else {
996 echo '<tr>
997 <td scope="row" valign="top" style="width:400px !important">
998 <label>'. esc_html__('Manually Update .htaccess', 'loginizer') . '</label><br>
999 <span class="exp">' . esc_html__('You can manually update your .htaccess by adding the given code at the top of your .htaccess file', 'loginizer'). '</span>
1000 </td>
1001 <td valign="top">
1002 <textarea rows="8" readonly class="lz-htaccess-textarea">' . trim($rule) . '</textarea>
1003 </td>
1004 </tr>';
1005 }
1006
1007 }