PluginProbe
Loginizer / 2.0.1
Loginizer v2.0.1
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 2.0.1, at main/settings/security.php

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