WP Security Audit Log - Version 4.0.2

Version Description

(2020-02-28) =

  • Security fix

    • Added authentication check for the first-time install wizard. This addresses an edge case in which if the wizard was never completed by the user, unauthenticated users could run the wizard and give access to the plugin settings to WordPress users.
  • Improvements

    • Removed the setting / functionality to allow access to users with non-admin role to the plugin settings. Now users who require access to the plugin settings need to have the admin role.
    • Removed the "activity log view access" and the "exclude objects" steps from the install wizard. These are advanced settings.
    • Check the role of users trying to import settings file and deny if it does not have admin role.
Download this release

Release Info

Developer WPWhiteSecurity
Plugin Icon 128x128 WP Security Audit Log
Version 4.0.2
Comparing to
See all releases

Code changes from version 4.0.1 to 4.0.2

classes/Update/Task/SettingsEditConfig.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Task to handle updating the settings that allow different users permission
4
+ * to edit the plugin settings.
5
+ *
6
+ * @package Wsal
7
+ * @since 4.0.2
8
+ */
9
+
10
+ namespace WSAL\Update\Task;
11
+
12
+ /**
13
+ *
14
+ */
15
+ class SettingsEditConfig {
16
+
17
+ /**
18
+ * Holds the main plugin instance to work on.
19
+ *
20
+ * @var \WpSecurityAuditLog
21
+ */
22
+ private $wsal;
23
+
24
+ /**
25
+ * Setups up the class properties.
26
+ *
27
+ * @method __construct
28
+ * @since 4.02
29
+ * @param \WpSecurityAuditLog $wsal An instance of the main plugin.
30
+ */
31
+ public function __construct( $wsal ) {
32
+ $this->wsal = $wsal;
33
+ }
34
+ /**
35
+ * Loop through an array of cron tasks and remap them if the name changed.
36
+ *
37
+ * @method run
38
+ * @since 4.0.2
39
+ */
40
+ public function run() {
41
+ $restrict_setting_edit_type = $this->wsal->GetGlobalOption( 'restrict-plugin-settings' );
42
+ // If it's anything other than 'only_me' then we just delete the keys
43
+ // and revert to default settings.
44
+ if ( 'only_me' !== $restrict_setting_edit_type ) {
45
+ $this->wsal->DeleteByName( 'wsal-restrict-plugin-settings' );
46
+ $this->wsal->DeleteByName( 'wsal-plugin-editors' );
47
+ $this->wsal->DeleteByName( 'wsal-restrict-admins' );
48
+ }
49
+ }
50
+
51
+ }
classes/Views/Settings.php CHANGED
@@ -236,6 +236,10 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
236
  * @throws Exception - Unrecognized settings tab error.
237
  */
238
  protected function Save() {
 
 
 
 
239
  // Call respective tab save functions if they are set. Nonce is already verified at this point.
240
  if ( ! empty( $this->current_tab ) && ! empty( $this->wsal_setting_tabs[ $this->current_tab ]['save'] ) ) {
241
  call_user_func( $this->wsal_setting_tabs[ $this->current_tab ]['save'] );
@@ -745,7 +749,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
745
  echo wp_kses(
746
  sprintf(
747
  /* translators: Learn more link. */
748
- esc_html__( 'By default only users with administrator or super administrator (multisite) roles can change the settings of the plugin. Though you can change these privileges from this section - %s.', 'wp-security-audit-log' ),
749
  '<a href="https://www.wpsecurityauditlog.com/support-documentation/managing-wordpress-activity-log-plugin-privileges/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . __( 'learn more', 'wp-security-audit-log' ) . '</a>'
750
  ),
751
  $allowed_tags
@@ -766,41 +770,16 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
766
  <br/>
767
  <label for="only_admins">
768
  <input type="radio" name="restrict-plugin-settings" id="only_admins" value="only_admins" <?php checked( $restrict_settings, 'only_admins' ); ?> />
769
- <?php esc_html_e( 'Only administrators', 'wp-security-audit-log' ); ?>
 
 
 
 
 
 
 
770
  </label>
771
  <br/>
772
- <?php if ( $this->_plugin->IsMultisite() ) : ?>
773
- <label for="only_superadmins">
774
- <input type="radio" name="restrict-plugin-settings" id="only_superadmins" value="only_superadmins" <?php checked( $restrict_settings, 'only_superadmins' ); ?> />
775
- <?php esc_html_e( 'Only superadmins', 'wp-security-audit-log' ); ?>
776
- </label>
777
- <br/>
778
- <?php endif; ?>
779
- <label for="only_selected_users">
780
- <input type="radio" name="restrict-plugin-settings" id="only_selected_users" value="only_selected_users" <?php checked( $restrict_settings, 'only_selected_users' ); ?> />
781
- <?php esc_html_e( 'All these users or users with these roles', 'wp-security-audit-log' ); ?>
782
- </label>
783
- <p class="description"><?php esc_html_e( 'Specify the username or the users which can change the plugin settings. You can also specify roles.', 'wp-security-audit-log' ); ?></p>
784
- <label>
785
- <input type="text" id="EditorQueryBox" style="width: 250px;">
786
- <input type="button" id="EditorQueryAdd" style="" class="button-primary" value="Add">
787
- </label>
788
- <div id="EditorList">
789
- <?php
790
- foreach ( $this->_plugin->settings->GetAllowedPluginEditors() as $item ) :
791
- if ( wp_get_current_user()->user_login === $item ) {
792
- continue;
793
- }
794
- ?>
795
- <span class="sectoken-<?php echo esc_attr( $this->GetTokenType( $item ) ); ?>">
796
- <input type="hidden" name="Editors[]" value="<?php echo esc_attr( $item ); ?>"/>
797
- <?php echo esc_html( $item ); ?>
798
- <?php if ( wp_get_current_user()->user_login !== $item ) : ?>
799
- <a href="javascript:;" title="Remove">&times;</a>
800
- <?php endif; ?>
801
- </span>
802
- <?php endforeach; ?>
803
- </div>
804
  </fieldset>
805
  </td>
806
  </tr>
@@ -2012,6 +1991,11 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
2012
  * Save: `Import/Export`
2013
  */
2014
  private function tab_import_settings_save() {
 
 
 
 
 
2015
  if ( isset( $_FILES['import-settings'] ) ) {
2016
  if ( 0 === $_FILES['import-settings']['error'] ) {
2017
  $filename = isset( $_FILES['import-settings']['name'] ) ? sanitize_text_field( wp_unslash( $_FILES['import-settings']['name'] ) ) : false;
236
  * @throws Exception - Unrecognized settings tab error.
237
  */
238
  protected function Save() {
239
+ // Bail early if user does not have sufficient permissions to save.
240
+ if ( ! $this->_plugin->settings->CurrentUserCan( 'edit' ) ) {
241
+ throw new Exception( esc_html__( 'Current user is not allowed to save settings.', 'wp-security-audit-log' ) );
242
+ }
243
  // Call respective tab save functions if they are set. Nonce is already verified at this point.
244
  if ( ! empty( $this->current_tab ) && ! empty( $this->wsal_setting_tabs[ $this->current_tab ]['save'] ) ) {
245
  call_user_func( $this->wsal_setting_tabs[ $this->current_tab ]['save'] );
749
  echo wp_kses(
750
  sprintf(
751
  /* translators: Learn more link. */
752
+ esc_html__( 'By default only users with administrator role (single site) and super administrator role (multisite) can change the settings of the plugin. Though you can restrict the privileges to just your user - %s.', 'wp-security-audit-log' ),
753
  '<a href="https://www.wpsecurityauditlog.com/support-documentation/managing-wordpress-activity-log-plugin-privileges/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . __( 'learn more', 'wp-security-audit-log' ) . '</a>'
754
  ),
755
  $allowed_tags
770
  <br/>
771
  <label for="only_admins">
772
  <input type="radio" name="restrict-plugin-settings" id="only_admins" value="only_admins" <?php checked( $restrict_settings, 'only_admins' ); ?> />
773
+ <?php
774
+ if ( $this->_plugin->IsMultisite() ) {
775
+ esc_html_e( 'Only superadmins', 'wp-security-audit-log' );
776
+ } else {
777
+ esc_html_e( 'Only administrators', 'wp-security-audit-log' );
778
+ }
779
+ ?>
780
+ <?php ?>
781
  </label>
782
  <br/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
783
  </fieldset>
784
  </td>
785
  </tr>
1991
  * Save: `Import/Export`
1992
  */
1993
  private function tab_import_settings_save() {
1994
+ // bail early if user does not have sufficient permissions to import.
1995
+ if ( ! $this->_plugin->settings->CurrentUserCan( 'edit' ) ) {
1996
+ echo '<div class="notice notice-error"><p>' . esc_html__( 'Current user is not allowed to import files.', 'wp-security-audit-log' ) . '</p></div>';
1997
+ return;
1998
+ }
1999
  if ( isset( $_FILES['import-settings'] ) ) {
2000
  if ( 0 === $_FILES['import-settings']['error'] ) {
2001
  $filename = isset( $_FILES['import-settings']['name'] ) ? sanitize_text_field( wp_unslash( $_FILES['import-settings']['name'] ) ) : false;
classes/Views/SetupWizard.php CHANGED
@@ -42,6 +42,20 @@ final class WSAL_Views_SetupWizard {
42
  */
43
  private $current_step;
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  /**
46
  * Method: Constructor.
47
  *
@@ -50,16 +64,19 @@ final class WSAL_Views_SetupWizard {
50
  public function __construct( WpSecurityAuditLog $wsal ) {
51
  $this->wsal = $wsal;
52
 
 
 
 
53
  add_action( 'admin_menu', array( $this, 'admin_menus' ), 10 );
54
- add_action( 'admin_init', array( $this, 'setup_page' ), 10 );
55
  add_action( 'wp_ajax_setup_check_security_token', array( $this, 'setup_check_security_token' ) );
 
56
  }
57
 
58
  /**
59
  * Ajax handler to verify setting token.
60
  */
61
  public function setup_check_security_token() {
62
- if ( ! $this->wsal->settings->CurrentUserCan( 'view' ) ) {
63
  echo wp_json_encode(
64
  array(
65
  'success' => false,
@@ -69,10 +86,8 @@ final class WSAL_Views_SetupWizard {
69
  die();
70
  }
71
 
72
- //@codingStandardsIgnoreStart
73
- $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( $_POST['nonce'] ) : false;
74
- $token = isset( $_POST['token'] ) ? sanitize_text_field( $_POST['token'] ) : false;
75
- //@codingStandardsIgnoreEnd
76
 
77
  if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wsal-verify-wizard-page' ) ) {
78
  echo wp_json_encode(
@@ -117,7 +132,7 @@ final class WSAL_Views_SetupWizard {
117
  public function setup_page() {
118
  // Get page argument from $_GET array.
119
  $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
120
- if ( empty( $page ) || 'wsal-setup' !== $page ) {
121
  return;
122
  }
123
 
@@ -154,16 +169,6 @@ final class WSAL_Views_SetupWizard {
154
  'content' => array( $this, 'wsal_step_log_retention' ),
155
  'save' => array( $this, 'wsal_step_log_retention_save' ),
156
  ),
157
- 'access' => array(
158
- 'name' => __( 'Access', 'wp-security-audit-log' ),
159
- 'content' => array( $this, 'wsal_step_access' ),
160
- 'save' => array( $this, 'wsal_step_access_save' ),
161
- ),
162
- 'exclude_object' => array(
163
- 'name' => __( 'Exclude Objects', 'wp-security-audit-log' ),
164
- 'content' => array( $this, 'wsal_step_exclude_object' ),
165
- 'save' => array( $this, 'wsal_step_exclude_object_save' ),
166
- ),
167
  'finish' => array(
168
  'name' => __( 'Finish', 'wp-security-audit-log' ),
169
  'content' => array( $this, 'wsal_step_finish' ),
@@ -184,6 +189,11 @@ final class WSAL_Views_SetupWizard {
184
  $current_step = filter_input( INPUT_GET, 'current-step', FILTER_SANITIZE_STRING );
185
  $this->current_step = ! empty( $current_step ) ? $current_step : current( array_keys( $this->wizard_steps ) );
186
 
 
 
 
 
 
187
  /**
188
  * Enqueue Styles.
189
  */
@@ -208,7 +218,7 @@ final class WSAL_Views_SetupWizard {
208
  // Data array.
209
  $data_array = array(
210
  'ajaxURL' => admin_url( 'admin-ajax.php' ),
211
- 'nonce' => wp_create_nonce( 'wsal-verify-wizard-page' ),
212
  'usersError' => esc_html__( 'Specified value in not a user.', 'wp-security-audit-log' ),
213
  'rolesError' => esc_html__( 'Specified value in not a role.', 'wp-security-audit-log' ),
214
  'ipError' => esc_html__( 'Specified value in not an IP address.', 'wp-security-audit-log' ),
@@ -223,7 +233,6 @@ final class WSAL_Views_SetupWizard {
223
  call_user_func( $this->wizard_steps[ $this->current_step ]['save'] );
224
  }
225
 
226
- ob_start();
227
  $this->setup_page_header();
228
  $this->setup_page_steps();
229
  $this->setup_page_content();
@@ -312,6 +321,17 @@ final class WSAL_Views_SetupWizard {
312
  return add_query_arg( 'current-step', $keys[ $step_index + 1 ] );
313
  }
314
 
 
 
 
 
 
 
 
 
 
 
 
315
  /**
316
  * Setup Page Content.
317
  */
@@ -319,14 +339,35 @@ final class WSAL_Views_SetupWizard {
319
  ?>
320
  <div class="wsal-setup-content">
321
  <?php
322
- if ( ! empty( $this->wizard_steps[ $this->current_step ]['content'] ) ) {
323
  call_user_func( $this->wizard_steps[ $this->current_step ]['content'] );
 
 
324
  }
325
  ?>
326
  </div>
327
  <?php
328
  }
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  /**
331
  * Step View: `Welcome`
332
  */
@@ -385,10 +426,14 @@ final class WSAL_Views_SetupWizard {
385
  // Check nonce.
386
  check_admin_referer( 'wsal-step-log-details' );
387
 
388
- // Save Log Details Step setting.
389
- // @codingStandardsIgnoreStart
390
- $log_details = isset( $_POST['wsal-details-level'] ) ? sanitize_text_field( $_POST['wsal-details-level'] ) : false;
391
- // @codingStandardsIgnoreEnd
 
 
 
 
392
 
393
  // Save log details option.
394
  $this->wsal->SetGlobalOption( 'details-level', $log_details );
@@ -441,7 +486,7 @@ final class WSAL_Views_SetupWizard {
441
  if ( isset( $_POST['wsal-frontend-login'] ) ) {
442
  $frontend_sensors = $this->wsal->settings->get_frontend_events(); // Get the frontend sensors setting.
443
  $login_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-login'] ) );
444
- $login_sensor = '0' === $login_sensor ? false : $login_sensor; // Update the sensor option.
445
 
446
  $frontend_sensors['login'] = $login_sensor;
447
  $this->wsal->settings->set_frontend_events( $frontend_sensors );
@@ -489,7 +534,7 @@ final class WSAL_Views_SetupWizard {
489
  if ( isset( $_POST['wsal-frontend-system'] ) ) {
490
  $frontend_sensors = $this->wsal->settings->get_frontend_events(); // Get the frontend sensors setting.
491
  $system_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-system'] ) );
492
- $system_sensor = '0' === $system_sensor ? false : $system_sensor; // Update the sensor option.
493
 
494
  $frontend_sensors['system'] = $system_sensor;
495
  $this->wsal->settings->set_frontend_events( $frontend_sensors );
@@ -538,7 +583,7 @@ final class WSAL_Views_SetupWizard {
538
  if ( isset( $_POST['wsal-frontend-register'] ) ) {
539
  $frontend_sensors = $this->wsal->settings->get_frontend_events(); // Get the frontend sensors setting.
540
  $register_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-register'] ) );
541
- $register_sensor = '0' === $register_sensor ? false : $register_sensor; // Update the sensor option.
542
 
543
  $frontend_sensors['register'] = $register_sensor;
544
  $this->wsal->settings->set_frontend_events( $frontend_sensors );
@@ -612,10 +657,14 @@ final class WSAL_Views_SetupWizard {
612
  // Verify nonce.
613
  check_admin_referer( 'wsal-step-log-retention' );
614
 
615
- // Save Log Retention Step setting.
616
- // @codingStandardsIgnoreStart
617
- $pruning_limit = isset( $_POST['wsal-pruning-limit'] ) ? sanitize_text_field( $_POST['wsal-pruning-limit'] ) : false;
618
- // @codingStandardsIgnoreEnd
 
 
 
 
619
 
620
  // Save log retention setting.
621
  if ( ! empty( $pruning_limit ) ) {
@@ -655,221 +704,6 @@ final class WSAL_Views_SetupWizard {
655
  return $this->wsal->settings->get_token_type( $token );
656
  }
657
 
658
- /**
659
- * Step View: `Access`
660
- */
661
- private function wsal_step_access() {
662
- ?>
663
- <form method="post" class="wsal-setup-form">
664
- <?php wp_nonce_field( 'wsal-step-access' ); ?>
665
- <h4>
666
- <?php esc_html_e( 'By default only the users with administrator role can access the WordPress activity log. Would you like to allow any other user or users with a role to access the WordPress activity log?', 'wp-security-audit-log' ); ?>
667
- </h4>
668
- <fieldset>
669
- <label for="no">
670
- <input id="no" name="wsal-access" type="radio" value="no" checked />
671
- <?php esc_html_e( 'No', 'wp-security-audit-log' ); ?>
672
- </label>
673
- <br />
674
- <label for="yes">
675
- <input id="yes" name="wsal-access" type="radio" value="yes" />
676
- <?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?>
677
- </label>
678
- </fieldset>
679
-
680
- <fieldset>
681
- <label for="editor-users-box">
682
- <span><?php esc_html_e( 'Usernames: ', 'wp-security-audit-log' ); ?></span>
683
- <input id="editor-users-box" class="editor-query-box" name="editor-users-box" type="text" />
684
- <a href="javascript:;" class="button button-primary" id="editor-users-add">
685
- <?php esc_html_e( 'ADD', 'wp-security-audit-log' ); ?>
686
- </a>
687
- </label>
688
- <br />
689
- <label for="editor-roles-box">
690
- <span><?php esc_html_e( 'Roles: ', 'wp-security-audit-log' ); ?></span>
691
- <input id="editor-roles-box" class="editor-query-box" name="editor-roles-box" type="text" />
692
- <a href="javascript:;" class="button button-primary" id="editor-roles-add">
693
- <?php esc_html_e( 'ADD', 'wp-security-audit-log' ); ?>
694
- </a>
695
- </label>
696
- <br />
697
- <div id="editor-list">
698
- <?php foreach ( $this->wsal->settings->GetAllowedPluginEditors() as $item ) : ?>
699
- <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
700
- <input type="hidden" name="editors[]" value="<?php echo esc_attr( $item ); ?>"/>
701
- <?php echo esc_html( $item ); ?>
702
- <?php if ( wp_get_current_user()->user_login !== $item ) { ?>
703
- <a href="javascript:;" title="Remove">&times;</a>
704
- <?php } ?>
705
- </span>
706
- <?php endforeach; ?>
707
- </div>
708
- </fieldset>
709
-
710
- <p class="description">
711
- <?php esc_html_e( 'Note: you can change the WordPress activity log privileges settings at any time from the plugin settings.', 'wp-security-audit-log' ); ?>
712
- </p>
713
-
714
- <div class="wsal-setup-actions">
715
- <button class="button button-primary"
716
- type="submit"
717
- name="save_step"
718
- value="<?php esc_attr_e( 'Next', 'wp-security-audit-log' ); ?>">
719
- <?php esc_html_e( 'Next', 'wp-security-audit-log' ); ?>
720
- </button>
721
- </div>
722
- </form>
723
-
724
- <p class="description">
725
- <em><?php echo esc_html__( 'The WordPress activity log contains sensitive data such as who logged in, from where, when, and what they did.', 'wp-security-audit-log' ); ?></em>
726
- </p>
727
- <?php
728
- }
729
-
730
- /**
731
- * Step Save: `Access`
732
- */
733
- private function wsal_step_access_save() {
734
- // Verify nonce.
735
- check_admin_referer( 'wsal-step-access' );
736
-
737
- // Get Access Step setting.
738
- // @codingStandardsIgnoreStart
739
- $wsal_access = isset( $_POST['wsal-access'] ) ? sanitize_text_field( $_POST['wsal-access'] ) : false;
740
- $wsal_editors = isset( $_POST['editors'] ) ? array_map( 'sanitize_text_field', $_POST['editors'] ) : false;
741
- // @codingStandardsIgnoreEnd
742
-
743
- if ( ! empty( $wsal_access ) && 'yes' === $wsal_access ) {
744
- if ( 1 === count( $wsal_editors ) && $this->wsal->settings->IsRestrictAdmins() ) {
745
- $this->wsal->settings->set_restrict_plugin_setting( 'only_me' );
746
- } else {
747
- $this->wsal->settings->set_restrict_plugin_setting( 'only_selected_users' );
748
- }
749
- $this->wsal->settings->SetAllowedPluginEditors( ! empty( $wsal_editors ) ? $wsal_editors : array() );
750
- } elseif ( ! empty( $wsal_access ) && 'no' === $wsal_access ) {
751
- if ( $this->wsal->settings->IsRestrictAdmins() ) {
752
- $this->wsal->settings->set_restrict_plugin_setting( 'only_me' );
753
- } else {
754
- $this->wsal->settings->SetAllowedPluginEditors( array() );
755
- }
756
- }
757
-
758
- wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
759
- exit();
760
- }
761
-
762
- /**
763
- * Step View: `Exclude Objects`
764
- */
765
- private function wsal_step_exclude_object() {
766
- ?>
767
- <form method="post" class="wsal-setup-form">
768
- <?php wp_nonce_field( 'wsal-step-exclude-objects' ); ?>
769
- <p>
770
- <?php esc_html_e( 'The plugin will keep a log of everything that happens on your WordPress website. If you would like to exclude a particular user, users with a role or an IP address from the log specify them below. If not just click the Next button.', 'wp-security-audit-log' ); ?>
771
- </p>
772
-
773
- <fieldset>
774
- <label for="exuser-query-box">
775
- <span><?php esc_html_e( 'Usernames: ', 'wp-security-audit-log' ); ?></span>
776
- <input id="exuser-query-box" class="exuser-query-box" name="exuser-query-box" type="text" />
777
- <a href="javascript:;" class="button button-primary" id="exuser-query-add">
778
- <?php esc_html_e( 'ADD', 'wp-security-audit-log' ); ?>
779
- </a>
780
- </label>
781
- <div id="exuser-list">
782
- <?php foreach ( $this->wsal->settings->GetExcludedMonitoringUsers() as $item ) : ?>
783
- <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
784
- <input type="hidden" name="exusers[]" value="<?php echo esc_attr( $item ); ?>"/>
785
- <?php echo esc_html( $item ); ?>
786
- <a href="javascript:;" title="Remove">&times;</a>
787
- </span>
788
- <?php endforeach; ?>
789
- </div>
790
- </fieldset>
791
-
792
- <fieldset>
793
- <label for="exrole-query-box">
794
- <span><?php esc_html_e( 'Roles: ', 'wp-security-audit-log' ); ?></span>
795
- <input id="exrole-query-box" class="exrole-query-box" name="exrole-query-box" type="text" />
796
- <a href="javascript:;" class="button button-primary" id="exrole-query-add">
797
- <?php esc_html_e( 'ADD', 'wp-security-audit-log' ); ?>
798
- </a>
799
- </label>
800
- <div id="exrole-list">
801
- <?php foreach ( $this->wsal->settings->GetExcludedMonitoringRoles() as $item ) : ?>
802
- <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
803
- <input type="hidden" name="exroles[]" value="<?php echo esc_attr( $item ); ?>"/>
804
- <?php echo esc_html( $item ); ?>
805
- <a href="javascript:;" title="Remove">&times;</a>
806
- </span>
807
- <?php endforeach; ?>
808
- </div>
809
- </fieldset>
810
-
811
- <fieldset>
812
- <label for="ipaddr-query-box">
813
- <span><?php esc_html_e( 'IP Address: ', 'wp-security-audit-log' ); ?></span>
814
- <input id="ipaddr-query-box" class="ipaddr-query-box" name="ipaddr-query-box" type="text" />
815
- <a href="javascript:;" class="button button-primary" id="ipaddr-query-add">
816
- <?php esc_html_e( 'ADD', 'wp-security-audit-log' ); ?>
817
- </a>
818
- </label>
819
- <div id="ipaddr-list">
820
- <?php foreach ( $this->wsal->settings->GetExcludedMonitoringIP() as $item ) : ?>
821
- <span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
822
- <input type="hidden" name="ipaddrs[]" value="<?php echo esc_attr( $item ); ?>"/>
823
- <?php echo esc_html( $item ); ?>
824
- <a href="javascript:;" title="Remove">&times;</a>
825
- </span>
826
- <?php endforeach; ?>
827
- </div>
828
- </fieldset>
829
-
830
- <p class="description">
831
- <?php esc_html_e( 'Note: You can change these exclusions anytime from the plugin settings.', 'wp-security-audit-log' ); ?>
832
- </p>
833
-
834
- <div class="wsal-setup-actions">
835
- <button class="button button-primary"
836
- type="submit"
837
- name="save_step"
838
- value="<?php esc_attr_e( 'Next', 'wp-security-audit-log' ); ?>">
839
- <?php esc_html_e( 'Next', 'wp-security-audit-log' ); ?>
840
- </button>
841
- </div>
842
- </form>
843
-
844
- <p class="description">
845
- <em><?php echo esc_html__( 'The WordPress activity log contains sensitive data such as who logged in, from where, when and what they did.', 'wp-security-audit-log' ); ?></em>
846
- </p>
847
- <?php
848
- }
849
-
850
- /**
851
- * Step Save: `Exclude Objects`
852
- */
853
- private function wsal_step_exclude_object_save() {
854
- // Verify nonce.
855
- check_admin_referer( 'wsal-step-exclude-objects' );
856
-
857
- // Get exclude objects step settings.
858
- // @codingStandardsIgnoreStart
859
- $wsal_exusers = isset( $_POST['exusers'] ) ? array_map( 'sanitize_text_field', $_POST['exusers'] ) : false;
860
- $wsal_exroles = isset( $_POST['exroles'] ) ? array_map( 'sanitize_text_field', $_POST['exroles'] ) : false;
861
- $wsal_ipaddrs = isset( $_POST['ipaddrs'] ) ? array_map( 'sanitize_text_field', $_POST['ipaddrs'] ) : false;
862
- // @codingStandardsIgnoreEnd
863
-
864
- // Save the settings.
865
- $this->wsal->settings->SetExcludedMonitoringUsers( ! empty( $wsal_exusers ) ? $wsal_exusers : array() );
866
- $this->wsal->settings->SetExcludedMonitoringRoles( ! empty( $wsal_exroles ) ? $wsal_exroles : array() );
867
- $this->wsal->settings->SetExcludedMonitoringIP( ! empty( $wsal_ipaddrs ) ? $wsal_ipaddrs : array() );
868
-
869
- wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
870
- exit();
871
- }
872
-
873
  /**
874
  * Step View: `Finish`
875
  */
42
  */
43
  private $current_step;
44
 
45
+ /**
46
+ * List of all the valid inputs we will accept for log levels.
47
+ *
48
+ * @var array
49
+ */
50
+ private $valid_log_levels = array( 'geek', 'basic' );
51
+
52
+ /**
53
+ * List if all the valid inputs we will accept for prune times.
54
+ *
55
+ * @var array
56
+ */
57
+ private $valid_prune_times = array( '6', '12', 'none' );
58
+
59
  /**
60
  * Method: Constructor.
61
  *
64
  public function __construct( WpSecurityAuditLog $wsal ) {
65
  $this->wsal = $wsal;
66
 
67
+ if ( current_user_can( 'manage_options' ) ) {
68
+ add_action( 'admin_init', array( $this, 'setup_page' ), 10 );
69
+ }
70
  add_action( 'admin_menu', array( $this, 'admin_menus' ), 10 );
 
71
  add_action( 'wp_ajax_setup_check_security_token', array( $this, 'setup_check_security_token' ) );
72
+
73
  }
74
 
75
  /**
76
  * Ajax handler to verify setting token.
77
  */
78
  public function setup_check_security_token() {
79
+ if ( ! current_user_can( 'manage_options' ) ) {
80
  echo wp_json_encode(
81
  array(
82
  'success' => false,
86
  die();
87
  }
88
 
89
+ $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : false;
90
+ $token = isset( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : false;
 
 
91
 
92
  if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wsal-verify-wizard-page' ) ) {
93
  echo wp_json_encode(
132
  public function setup_page() {
133
  // Get page argument from $_GET array.
134
  $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
135
+ if ( empty( $page ) || 'wsal-setup' !== $page || ! ( current_user_can( 'manage_options' ) ) ) {
136
  return;
137
  }
138
 
169
  'content' => array( $this, 'wsal_step_log_retention' ),
170
  'save' => array( $this, 'wsal_step_log_retention_save' ),
171
  ),
 
 
 
 
 
 
 
 
 
 
172
  'finish' => array(
173
  'name' => __( 'Finish', 'wp-security-audit-log' ),
174
  'content' => array( $this, 'wsal_step_finish' ),
189
  $current_step = filter_input( INPUT_GET, 'current-step', FILTER_SANITIZE_STRING );
190
  $this->current_step = ! empty( $current_step ) ? $current_step : current( array_keys( $this->wizard_steps ) );
191
 
192
+ // check if current step is a valid one.
193
+ if ( ! array_key_exists( $this->current_step, $this->wizard_steps ) ) {
194
+ $this->current_step = 'invalid-step';
195
+ }
196
+
197
  /**
198
  * Enqueue Styles.
199
  */
218
  // Data array.
219
  $data_array = array(
220
  'ajaxURL' => admin_url( 'admin-ajax.php' ),
221
+ 'nonce' => ( ( ! $this->wsal->settings->CurrentUserCan( 'edit' ) ) && ! 'invalid-step' === $this->current_step ) ? wp_create_nonce( 'wsal-verify-wizard-page' ) : '',
222
  'usersError' => esc_html__( 'Specified value in not a user.', 'wp-security-audit-log' ),
223
  'rolesError' => esc_html__( 'Specified value in not a role.', 'wp-security-audit-log' ),
224
  'ipError' => esc_html__( 'Specified value in not an IP address.', 'wp-security-audit-log' ),
233
  call_user_func( $this->wizard_steps[ $this->current_step ]['save'] );
234
  }
235
 
 
236
  $this->setup_page_header();
237
  $this->setup_page_steps();
238
  $this->setup_page_content();
321
  return add_query_arg( 'current-step', $keys[ $step_index + 1 ] );
322
  }
323
 
324
+ /**
325
+ * Gets a link to the first wizard step.
326
+ *
327
+ * @method get_welcome_step
328
+ * @since 4.0.2
329
+ * @return string
330
+ */
331
+ private function get_welcome_step() {
332
+ return remove_query_arg( 'current-step' );
333
+ }
334
+
335
  /**
336
  * Setup Page Content.
337
  */
339
  ?>
340
  <div class="wsal-setup-content">
341
  <?php
342
+ if ( isset( $this->wizard_steps[ $this->current_step ]['content'] ) && ! empty( $this->wizard_steps[ $this->current_step ]['content'] && is_callable( $this->wizard_steps[ $this->current_step ]['content'] ) ) ) {
343
  call_user_func( $this->wizard_steps[ $this->current_step ]['content'] );
344
+ } else {
345
+ $this->render_invalid_step();
346
  }
347
  ?>
348
  </div>
349
  <?php
350
  }
351
 
352
+ /**
353
+ * Render method for any invalid steps a user happens to land on.
354
+ *
355
+ * @method render_invalid_step
356
+ * @since 4.0.2
357
+ */
358
+ private function render_invalid_step() {
359
+ ?>
360
+ <p><?php
361
+ printf(
362
+ /* translators: 1 - an opening link tag, 2 - a closing link tag. */
363
+ esc_html__( 'You have reached an invaild step - %1$sreturn to the start of the wizard%2$s.', 'wp-security-audit-log' ),
364
+ '<a href="' . esc_url( $this->get_welcome_step() ) . '">',
365
+ '</a>'
366
+ );
367
+ ?></p>
368
+ <?php
369
+ }
370
+
371
  /**
372
  * Step View: `Welcome`
373
  */
426
  // Check nonce.
427
  check_admin_referer( 'wsal-step-log-details' );
428
 
429
+ // Get Log Details Step setting.
430
+ $log_details = isset( $_POST['wsal-details-level'] ) ? sanitize_text_field( wp_unslash( $_POST['wsal-details-level'] ) ) : false;
431
+
432
+ // Validate we have a level that is allowed.
433
+ if ( ! in_array( $log_details, $this->valid_log_levels, true ) ) {
434
+ // if we have an unexpected log level then use default: 'geek'.
435
+ $log_details = $this->valid_log_levels[0];
436
+ }
437
 
438
  // Save log details option.
439
  $this->wsal->SetGlobalOption( 'details-level', $log_details );
486
  if ( isset( $_POST['wsal-frontend-login'] ) ) {
487
  $frontend_sensors = $this->wsal->settings->get_frontend_events(); // Get the frontend sensors setting.
488
  $login_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-login'] ) );
489
+ $login_sensor = '1' === $login_sensor ? true : false; // Update the sensor option.
490
 
491
  $frontend_sensors['login'] = $login_sensor;
492
  $this->wsal->settings->set_frontend_events( $frontend_sensors );
534
  if ( isset( $_POST['wsal-frontend-system'] ) ) {
535
  $frontend_sensors = $this->wsal->settings->get_frontend_events(); // Get the frontend sensors setting.
536
  $system_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-system'] ) );
537
+ $system_sensor = '1' === $system_sensor ? true : false; // Update the sensor option.
538
 
539
  $frontend_sensors['system'] = $system_sensor;
540
  $this->wsal->settings->set_frontend_events( $frontend_sensors );
583
  if ( isset( $_POST['wsal-frontend-register'] ) ) {
584
  $frontend_sensors = $this->wsal->settings->get_frontend_events(); // Get the frontend sensors setting.
585
  $register_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-register'] ) );
586
+ $register_sensor = '1' === $register_sensor ? true : false; // Update the sensor option.
587
 
588
  $frontend_sensors['register'] = $register_sensor;
589
  $this->wsal->settings->set_frontend_events( $frontend_sensors );
657
  // Verify nonce.
658
  check_admin_referer( 'wsal-step-log-retention' );
659
 
660
+ // Get log retention time setting.
661
+ $pruning_limit = isset( $_POST['wsal-pruning-limit'] ) ? sanitize_text_field( wp_unslash( $_POST['wsal-pruning-limit'] ) ) : false;
662
+
663
+ // validate the prune time.
664
+ if ( ! in_array( (string) $pruning_limit, $this->valid_prune_times, true ) ) {
665
+ // if $pruning_limit is not valid value then use default - 6.
666
+ $pruning_limit = $this->valid_prune_times[0];
667
+ }
668
 
669
  // Save log retention setting.
670
  if ( ! empty( $pruning_limit ) ) {
704
  return $this->wsal->settings->get_token_type( $token );
705
  }
706
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
  /**
708
  * Step View: `Finish`
709
  */
readme.txt CHANGED
@@ -5,8 +5,8 @@ License: GPLv3
5
  License URI: https://www.gnu.org/licenses/gpl.html
6
  Tags: wordpress security plugin, wordpress security audit log, audit log, activity logs, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, SMS messages, tracking, user tracking, user activity report, wordpress audit trail
7
  Requires at least: 3.6
8
- Tested up to: 5.3.2
9
- Stable tag: 4.0.1
10
  Requires PHP: 5.5
11
 
12
  An easy to use & comprehensive WordPress activity log plugin to log all changes on WordPress sites & multisite networks.
@@ -204,31 +204,17 @@ Please refer to our [Support & Documentation pages](https://www.wpsecurityauditl
204
 
205
  == Changelog ==
206
 
207
- = 4.0.1 (2020-02-13) =
208
 
209
- Release notes: [Update 4.0.1 - activity logs for WPForms](https://www.wpsecurityauditlog.com/releases/update-4-0-1/)
210
 
211
- * **New features**
212
-
213
- * [Activity logs for WPForms](http://www.wpsecurityauditlog.com/integrations/activity-log-wpforms/)
214
- * One-click installation and activation feature for new third party plugins add-ons.
215
- * New Third Party Plugins tab in Enable/Disable Events section to allow users to install add-ons for third party plugins.
216
- * Added the new event types "Renamed" and "Duplicated" (more on [activity log event types](https://www.wpsecurityauditlog.com/support-documentation/objects-event-types-wordpress-activity-log/)).
217
- * Added several new [hooks in the plugin](https://www.wpsecurityauditlog.com/support-documentation/list-hooks/), mainly to allow custom editor link, to add custom column to the logs viewer, to add new event types and objects.
218
 
219
  * **Improvements**
220
 
221
- * Updated event IDs 2123, 2062, 2084, 9077 and 9071 so they now use the "Renamed" event type.
222
- * Updated the [activity log severity levels](https://www.wpsecurityauditlog.com/support-documentation/severity-levels-wordpress-activity-log/) definitions in defaults.php)
223
- * Updated / improved some of the help text messages.
224
- * Plugin does not automatically retrieve the IP addresses and latest change of logged in users if there are 100+ sessions (performance improvement).
225
- * Localized text in JS files.
226
- * Started removing obsolete code.
227
- * Added new filter to allow custom %EditorLinkWPForm% from custom events add-ons.
228
-
229
- * **Bug fixes**
230
-
231
- * Only the path of the added, modified or deleted file was reported in daily summary email.
232
 
233
  = Earlier versions =
234
 
5
  License URI: https://www.gnu.org/licenses/gpl.html
6
  Tags: wordpress security plugin, wordpress security audit log, audit log, activity logs, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, SMS messages, tracking, user tracking, user activity report, wordpress audit trail
7
  Requires at least: 3.6
8
+ Tested up to: 5.4
9
+ Stable tag: 4.0.2
10
  Requires PHP: 5.5
11
 
12
  An easy to use & comprehensive WordPress activity log plugin to log all changes on WordPress sites & multisite networks.
204
 
205
  == Changelog ==
206
 
207
+ = 4.0.2 (2020-02-28) =
208
 
209
+ * **Security fix**
210
 
211
+ * Added authentication check for the first-time install wizard. This addresses an edge case in which if the wizard was never completed by the user, unauthenticated users could run the wizard and give access to the plugin settings to WordPress users.
 
 
 
 
 
 
212
 
213
  * **Improvements**
214
 
215
+ * Removed the setting / functionality to allow access to users with non-admin role to the plugin settings. Now users who require access to the plugin settings need to have the admin role.
216
+ * Removed the "activity log view access" and the "exclude objects" steps from the install wizard. These are advanced settings.
217
+ * Check the role of users trying to import settings file and deny if it does not have admin role.
 
 
 
 
 
 
 
 
218
 
219
  = Earlier versions =
220
 
wp-security-audit-log.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin URI: http://www.wpsecurityauditlog.com/
5
  * Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  * Author: WP White Security
7
- * Version: 4.0.1
8
  * Text Domain: wp-security-audit-log
9
  * Author URI: http://www.wpwhitesecurity.com/
10
  * License: GPL2
@@ -46,7 +46,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
46
  *
47
  * @var string
48
  */
49
- public $version = '4.0.1';
50
 
51
  // Plugin constants.
52
  const PLG_CLS_PRFX = 'WSAL_';
@@ -400,7 +400,9 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
400
  add_action( 'admin_footer', array( $this, 'render_footer' ) );
401
 
402
  // Plugin redirect on activation.
403
- add_action( 'admin_init', array( $this, 'wsal_plugin_redirect' ), 10 );
 
 
404
 
405
  // Handle admin Disable Custom Field.
406
  add_action( 'wp_ajax_AjaxDisableCustomField', array( $this, 'AjaxDisableCustomField' ) );
@@ -1522,6 +1524,22 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
1522
  }
1523
  );
1524
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1525
  }
1526
  }
1527
 
4
  * Plugin URI: http://www.wpsecurityauditlog.com/
5
  * Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  * Author: WP White Security
7
+ * Version: 4.0.2
8
  * Text Domain: wp-security-audit-log
9
  * Author URI: http://www.wpwhitesecurity.com/
10
  * License: GPL2
46
  *
47
  * @var string
48
  */
49
+ public $version = '4.0.2';
50
 
51
  // Plugin constants.
52
  const PLG_CLS_PRFX = 'WSAL_';
400
  add_action( 'admin_footer', array( $this, 'render_footer' ) );
401
 
402
  // Plugin redirect on activation.
403
+ if ( current_user_can( 'manage_options' ) ) {
404
+ add_action( 'admin_init', array( $this, 'wsal_plugin_redirect' ) );
405
+ }
406
 
407
  // Handle admin Disable Custom Field.
408
  add_action( 'wp_ajax_AjaxDisableCustomField', array( $this, 'AjaxDisableCustomField' ) );
1524
  }
1525
  );
1526
  }
1527
+
1528
+ /**
1529
+ * Upgrade routine for versions of the plugin prior to 4.0.2
1530
+ *
1531
+ * @since 4.0.2
1532
+ */
1533
+ if ( version_compare( $old_version, '4.0.1', '<=' ) ) {
1534
+ add_action(
1535
+ 'init',
1536
+ function() {
1537
+ require_once 'classes/Update/Task/SettingsEditConfig.php';
1538
+ $settings_edit_update = new WSAL\Update\Task\SettingsEditConfig( WpSecurityAuditLog::GetInstance() );
1539
+ $settings_edit_update->run();
1540
+ }
1541
+ );
1542
+ }
1543
  }
1544
  }
1545