iThemes Security (formerly Better WP Security) - Version 5.8.0

Version Description

  • Enhancement: Updated the lockouts notification email to a new design. This new design also cleaned up the translation strings to allow better translations.
    • New Feature: Added a "Protect Against Tabnapping" feature in the WordPress Tweaks section. Details of what this feature protects against can be found here: https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
    • Misc: Updated the description for the Lockout Period setting to indicate that the default value of 15 minutes is recommended.
Download this release

Release Info

Developer chrisjean
Plugin Icon 128x128 iThemes Security (formerly Better WP Security)
Version 5.8.0
Comparing to
See all releases

Code changes from version 5.7.1 to 5.8.0

better-wp-security.php CHANGED
@@ -6,7 +6,7 @@
6
  * Description: Take the guesswork out of WordPress security. iThemes Security offers 30+ ways to lock down WordPress in an easy-to-use WordPress security plugin.
7
  * Author: iThemes
8
  * Author URI: https://ithemes.com
9
- * Version: 5.7.1
10
  * Text Domain: better-wp-security
11
  * Network: True
12
  * License: GPLv2
6
  * Description: Take the guesswork out of WordPress security. iThemes Security offers 30+ ways to lock down WordPress in an easy-to-use WordPress security plugin.
7
  * Author: iThemes
8
  * Author URI: https://ithemes.com
9
+ * Version: 5.8.0
10
  * Text Domain: better-wp-security
11
  * Network: True
12
  * License: GPLv2
core/class-itsec-core.php CHANGED
@@ -624,6 +624,10 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
624
  return network_admin_url( 'admin.php?page=itsec&module=security-check' );
625
  }
626
 
 
 
 
 
627
  public static function set_interactive( $interactive ) {
628
  $self = self::get_instance();
629
  $self->interactive = (bool) $interactive;
624
  return network_admin_url( 'admin.php?page=itsec&module=security-check' );
625
  }
626
 
627
+ public static function get_settings_module_url( $module ) {
628
+ return network_admin_url( 'admin.php?page=itsec&module=' . $module );
629
+ }
630
+
631
  public static function set_interactive( $interactive ) {
632
  $self = self::get_instance();
633
  $self->interactive = (bool) $interactive;
core/class-itsec-lockout.php CHANGED
@@ -77,7 +77,6 @@ final class ITSEC_Lockout {
77
  * @return void
78
  */
79
  public function check_lockout( $user = false, $username = false ) {
80
-
81
  global $wpdb, $itsec_globals;
82
 
83
  $wpdb->hide_errors(); //Hide database errors in case the tables aren't there
@@ -913,133 +912,87 @@ final class ITSEC_Lockout {
913
  * @since 4.0
914
  *
915
  * @param string $host the host to lockout
916
- * @param int $user the user id to lockout
917
- * @param string $username the username to lockout
918
  * @param string $host_expiration when the host login expires
919
  * @param string $user_expiration when the user lockout expires
920
  * @param string $reason the reason for the lockout to show to the user
921
  *
922
  * @return void
923
  */
924
- private function send_lockout_email( $host, $user, $username, $host_expiration, $user_expiration, $reason ) {
925
-
926
- global $itsec_globals;
927
-
928
- $itsec_notify = ITSEC_Core::get_itsec_notify();
929
-
930
- if ( ! ITSEC_Modules::get_setting( 'global', 'digest_email' ) ) {
931
-
932
- $plural_text = __( 'has', 'better-wp-security' );
933
-
934
- //Tell which host was locked out
935
- if ( $host !== false ) {
936
-
937
- $host_text = sprintf( '%s, <a href="http://www.traceip.net/?query=%s"><strong>%s</strong></a>, ', __( 'host', 'better-wp-security' ), urlencode( $host ), sanitize_text_field( $host ) );
938
 
939
- $host_expiration_text = __( 'The host has been locked out ', 'better-wp-security' );
 
 
 
940
 
941
- if ( $host_expiration === false ) {
942
 
943
- $host_expiration_text .= '<strong>' . __( 'permanently', 'better-wp-security' ) . '</strong>';
944
- $release_text = sprintf( __( 'To release the host lockout you can remove the host from the <a href="%1$s">host list</a>.', 'better-wp-security' ), wp_login_url( ITSEC_Core::get_settings_page_url() ) );
 
945
 
946
- } else {
 
 
 
947
 
948
- $host_expiration_text .= sprintf( '<strong>%s %s</strong>', __( 'until', 'better-wp-security' ), sanitize_text_field( $host_expiration ) );
949
- $release_text = sprintf( __( 'To release the lockout please visit <a href="%1$s">the admin area</a>.', 'better-wp-security' ), wp_login_url( ITSEC_Core::get_settings_page_url() ) );
950
 
951
- }
 
 
 
 
 
 
952
 
 
 
 
 
953
  } else {
954
-
955
- $host_expiration_text = '';
956
- $host_text = '';
957
- $release_text = '';
958
-
959
  }
960
 
961
- $user_object = get_userdata( $user ); //try to get and actual user object
962
-
963
- //Tell them which user was locked out and setup the expiration copy
964
- if ( $user_object !== false || $username !== false ) {
965
-
966
- if ( $user_object !== false ) {
967
- $login = $user_object->user_login;
968
- } else {
969
- $login = sanitize_text_field( $username );
970
- }
971
-
972
- if ( $host_text === '' ) {
973
-
974
- $user_expiration_text = sprintf( '%s <strong>%s %s</strong>.', __( 'The user has been locked out', 'better-wp-security' ), __( 'until', 'better-wp-security' ), sanitize_text_field( $user_expiration ) );
975
-
976
- $user_text = sprintf( '%s, <strong>%s</strong>, ', __( 'user', 'better-wp-security' ), $login );
977
-
978
- $release_text = sprintf( __( 'To release the lockout please visit <a href="%1$s">the lockouts page</a>.', 'better-wp-security' ), wp_login_url( ITSEC_Core::get_settings_page_url() ) );
979
-
980
- } else {
981
-
982
- $user_expiration_text = sprintf( '%s <strong>%s %s</strong>.', __( 'and the user has been locked out', 'better-wp-security' ), __( 'until', 'better-wp-security' ), sanitize_text_field( $user_expiration ) );
983
- $plural_text = __( 'have', 'better-wp-security' );
984
- $user_text = sprintf( '%s, <strong>%s</strong>, ', __( 'and a user', 'better-wp-security' ), $login );
985
-
986
- if ( $host_expiration === false ) {
987
-
988
- $release_text = sprintf( __( 'To release the user lockout please visit <a href="%1$s">the lockouts page</a>.', 'better-wp-security' ), wp_login_url( ITSEC_Core::get_settings_page_url() ) );
989
-
990
- } else {
991
-
992
- $release_text = sprintf( __( 'To release the lockouts please visit <a href="%1$s">the lockouts page</a>.', 'better-wp-security' ), wp_login_url( ITSEC_Core::get_settings_page_url() ) );
993
 
994
- }
995
 
996
- }
 
997
 
998
- } else {
 
999
 
1000
- $user_expiration_text = '.';
1001
- $user_text = '';
1002
- $release_text = '';
 
1003
 
1004
- }
 
 
 
1005
 
1006
- //Put the copy all together
1007
- $body = sprintf(
1008
- '<p>%s,</p><p>%s %s %s %s %s <a href="%s">%s</a> %s <strong>%s</strong>.</p><p>%s %s</p><p>%s</p><p><em>*%s %s. %s <a href="%s">%s</a>.</em></p>',
1009
- __( 'Dear Site Admin', 'better-wp-security' ),
1010
- __( 'A', 'better-wp-security' ),
1011
- $host_text,
1012
- $user_text,
1013
- $plural_text,
1014
- __( ' been locked out of the WordPress site at', 'better-wp-security' ),
1015
- get_option( 'siteurl' ),
1016
- get_option( 'siteurl' ),
1017
- __( 'due to', 'better-wp-security' ),
1018
- sanitize_text_field( $reason ),
1019
- $host_expiration_text,
1020
- $user_expiration_text,
1021
- $release_text,
1022
- __( 'This email was generated automatically by' ),
1023
- $itsec_globals['plugin_name'],
1024
- __( 'To change your email preferences please visit', 'better-wp-security' ),
1025
- wp_login_url( ITSEC_Core::get_settings_page_url() ),
1026
- __( 'the plugin settings', 'better-wp-security' ) );
1027
-
1028
- //Setup the remainder of the email
1029
- $subject = '[' . get_option( 'siteurl' ) . '] ' . __( 'Site Lockout Notification', 'better-wp-security' );
1030
- $subject = apply_filters( 'itsec_lockout_email_subject', $subject );
1031
- $headers = 'From: ' . get_bloginfo( 'name' ) . ' <' . get_option( 'admin_email' ) . '>' . "\r\n";
1032
-
1033
- $args = array(
1034
- 'headers' => $headers,
1035
- 'message' => $body,
1036
- 'subject' => $subject,
1037
- );
1038
 
1039
- $itsec_notify->notify( $args );
1040
 
1041
- }
 
 
1042
 
 
1043
  }
1044
 
1045
  /**
77
  * @return void
78
  */
79
  public function check_lockout( $user = false, $username = false ) {
 
80
  global $wpdb, $itsec_globals;
81
 
82
  $wpdb->hide_errors(); //Hide database errors in case the tables aren't there
912
  * @since 4.0
913
  *
914
  * @param string $host the host to lockout
915
+ * @param int $user_id the user id to lockout
916
+ * @param string $username the username to lockout
917
  * @param string $host_expiration when the host login expires
918
  * @param string $user_expiration when the user lockout expires
919
  * @param string $reason the reason for the lockout to show to the user
920
  *
921
  * @return void
922
  */
923
+ private function send_lockout_email( $host, $user_id, $username, $host_expiration, $user_expiration, $reason ) {
924
+ if ( ITSEC_Modules::get_setting( 'global', 'digest_email' ) ) {
925
+ // The daily digest will show the relevant lockout details.
926
+ return;
927
+ }
 
 
 
 
 
 
 
 
 
928
 
929
+ if ( ! ITSEC_Modules::get_setting( 'global', 'email_notifications', true ) ) {
930
+ // Email notifications are disabled.
931
+ return;
932
+ }
933
 
 
934
 
935
+ $lockouts = array();
936
+ $show_remove_ip_ban_message = false;
937
+ $show_remove_lockout_message = false;
938
 
939
+ if ( false !== $user_id ) {
940
+ $user = get_userdata( $user_id );
941
+ $username = $user->user_login;
942
+ }
943
 
944
+ if ( false !== $username ) {
945
+ $show_remove_lockout_message = true;
946
 
947
+ $lockouts[] = array(
948
+ 'type' => 'user',
949
+ 'id' => $username,
950
+ 'until' => $user_expiration,
951
+ 'reason' => $reason,
952
+ );
953
+ }
954
 
955
+ if ( false !== $host ) {
956
+ if ( false === $host_expiration ) {
957
+ $host_expiration = __( 'Permanently', 'better-wp-security' );
958
+ $show_remove_ip_ban_message = true;
959
  } else {
960
+ $show_remove_lockout_message = true;
 
 
 
 
961
  }
962
 
963
+ $lockouts[] = array(
964
+ 'type' => 'host',
965
+ 'id' => '<a href="' . esc_url( ITSEC_Lib::get_trace_ip_link( $host ) ) . '">' . $host . '</a>',
966
+ 'until' => $host_expiration,
967
+ 'reason' => $reason,
968
+ );
969
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
970
 
 
971
 
972
+ require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-mail.php' );
973
+ $mail = new ITSEC_Mail();
974
 
975
+ $mail->add_header( esc_html__( 'Site Lockout Notification', 'better-wp-security' ), esc_html__( 'Site Lockout Notification', 'better-wp-security' ) );
976
+ $mail->add_lockouts_table( $lockouts );
977
 
978
+ if ( $show_remove_lockout_message ) {
979
+ $mail->add_text( __( 'Release lockouts from the Active Lockouts section of the settings page.', 'better-wp-security' ) );
980
+ $mail->add_button( __( 'Visit Settings Page', 'better-wp-security' ), wp_login_url( ITSEC_Core::get_settings_page_url() ) );
981
+ }
982
 
983
+ if ( $show_remove_ip_ban_message ) {
984
+ $mail->add_text( __( 'Release the permanent host ban from Ban Hosts list in the Banned Users section of the settings page.', 'better-wp-security' ) );
985
+ $mail->add_button( __( 'Visit Banned Users Settings', 'better-wp-security' ), wp_login_url( ITSEC_Core::get_settings_module_url( 'ban-users' ) ) );
986
+ }
987
 
988
+ $mail->add_footer();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
989
 
 
990
 
991
+ $subject = sprintf( esc_html__( '[%s] Site Lockout Notification', 'better-wp-security' ), esc_url( get_option( 'siteurl' ) ) );
992
+ $subject = apply_filters( 'itsec_lockout_email_subject', $subject );
993
+ $mail->set_subject( $subject, false );
994
 
995
+ $mail->send();
996
  }
997
 
998
  /**
core/class-itsec-notify.php CHANGED
@@ -88,7 +88,7 @@ class ITSEC_Notify {
88
  $send_email = false;
89
 
90
 
91
- require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-mailer.php' );
92
  $mail = new ITSEC_Mail();
93
  $mail->add_header( esc_html__( 'Daily Security Digest', 'better-wp-security' ), sprintf( wp_kses( __( 'Your Daily Security Digest for <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), date_i18n( get_option( 'date_format' ) ) ) );
94
  $mail->add_info_box( sprintf( wp_kses( __( 'The following is a summary of security related activity on your site: <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), get_option( 'siteurl' ) ) );
@@ -154,18 +154,6 @@ class ITSEC_Notify {
154
  $mail->add_footer();
155
 
156
 
157
- $raw_recipients = ITSEC_Modules::get_setting( 'global', 'notification_email' );
158
- $recipients = array();
159
-
160
- foreach ( $raw_recipients as $recipient ) {
161
- $recipient = trim( $recipient );
162
-
163
- if ( is_email( $recipient ) ) {
164
- $recipients[] = $recipient;
165
- }
166
- }
167
-
168
-
169
  $this->queue = array(
170
  'last_sent' => ITSEC_Core::get_current_time_gmt(),
171
  'messages' => array(),
@@ -174,9 +162,10 @@ class ITSEC_Notify {
174
  update_site_option( 'itsec_message_queue', $this->queue );
175
 
176
 
177
- $subject = sprintf( esc_html__( '[%s] Daily Security Digest', 'better-wp-security' ), esc_url( get_option( 'siteurl' ) ) );
 
178
 
179
- return $mail->send( $recipients, $subject );
180
  }
181
 
182
  /**
88
  $send_email = false;
89
 
90
 
91
+ require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-mail.php' );
92
  $mail = new ITSEC_Mail();
93
  $mail->add_header( esc_html__( 'Daily Security Digest', 'better-wp-security' ), sprintf( wp_kses( __( 'Your Daily Security Digest for <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), date_i18n( get_option( 'date_format' ) ) ) );
94
  $mail->add_info_box( sprintf( wp_kses( __( 'The following is a summary of security related activity on your site: <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), get_option( 'siteurl' ) ) );
154
  $mail->add_footer();
155
 
156
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  $this->queue = array(
158
  'last_sent' => ITSEC_Core::get_current_time_gmt(),
159
  'messages' => array(),
162
  update_site_option( 'itsec_message_queue', $this->queue );
163
 
164
 
165
+ $subject = esc_html__( 'Daily Security Digest', 'better-wp-security' );
166
+ $mail->set_subject( $subject );
167
 
168
+ return $mail->send();
169
  }
170
 
171
  /**
core/history.txt CHANGED
@@ -459,7 +459,7 @@
459
  Enhancement: Added a note that the Filter Request Methods setting in System Tweaks should not be enabled if the WordPress REST API is used. This is becasue the DELETE HTTP method is blocked when the setting is enabled.
460
  New Feature: Added setting to block requests for PHP files in the plugins directory in System Tweaks.
461
  New Feature: Added setting to block requests for PHP files in the themes directory in System Tweaks.
462
- 2.6.1
463
  Bug Fix: Remote IP is now correctly identified if the server is behind a reverse proxy that sends requests with more than one IP listed in a single header.
464
  Bug Fix: Fixed the link for a user in the logs page so that it properly works on sites that are inside a subdirectory.
465
  Bug Fix: Improved how Strong Password Enforcement works on password resets to improve compatibility with various plugins.
@@ -468,3 +468,7 @@
468
  Enhancement: Strong Password Enforcement now uses a PHP port of zxcvbn to ensure that a strong password was selected.
469
  Enhancement: All links in Security that have target="_blank" now have added rel attributes to protect against tabnapping.
470
  Misc: Updated remaining ip-lookup.net links to instead link to traceip.net in keeping with other links that were previously updated to traceip.net.
 
 
 
 
459
  Enhancement: Added a note that the Filter Request Methods setting in System Tweaks should not be enabled if the WordPress REST API is used. This is becasue the DELETE HTTP method is blocked when the setting is enabled.
460
  New Feature: Added setting to block requests for PHP files in the plugins directory in System Tweaks.
461
  New Feature: Added setting to block requests for PHP files in the themes directory in System Tweaks.
462
+ 2.6.1 - 2016-11-16 - Chris Jean
463
  Bug Fix: Remote IP is now correctly identified if the server is behind a reverse proxy that sends requests with more than one IP listed in a single header.
464
  Bug Fix: Fixed the link for a user in the logs page so that it properly works on sites that are inside a subdirectory.
465
  Bug Fix: Improved how Strong Password Enforcement works on password resets to improve compatibility with various plugins.
468
  Enhancement: Strong Password Enforcement now uses a PHP port of zxcvbn to ensure that a strong password was selected.
469
  Enhancement: All links in Security that have target="_blank" now have added rel attributes to protect against tabnapping.
470
  Misc: Updated remaining ip-lookup.net links to instead link to traceip.net in keeping with other links that were previously updated to traceip.net.
471
+ 2.7.0 - 2016-11-29 - Chris Jean
472
+ Enhancement: Updated the lockouts notification email to a new design. This new design also cleaned up the translation strings to allow better translations.
473
+ New Feature: Added a "Protect Against Tabnapping" feature in the WordPress Tweaks section. Details of what this feature protects against can be found here: https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
474
+ Misc: Updated the description for the Lockout Period setting to indicate that the default value of 15 minutes is recommended.
core/lib/{class-itsec-mailer.php → class-itsec-mail.php} RENAMED
@@ -2,6 +2,9 @@
2
 
3
  final class ITSEC_Mail {
4
  private $content = '';
 
 
 
5
  private $template_path = '';
6
 
7
  public function __construct() {
@@ -127,7 +130,7 @@ final class ITSEC_Mail {
127
  }
128
 
129
  public function add_lockouts_summary( $user_count, $host_count ) {
130
- $lockouts = $this->get_template( 'lockouts-table.html' );
131
 
132
  $replacements = array(
133
  'users_text' => esc_html__( 'Users', 'better-wp-security' ),
@@ -149,12 +152,84 @@ final class ITSEC_Mail {
149
  $this->content .= $module;
150
  }
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  public function get_content() {
153
  return $this->content;
154
  }
155
 
156
- public function send( $to, $subject, $attachments = array() ) {
157
- return wp_mail( $to, $subject, $this->content, array( 'Content-Type: text/html; charset=UTF-8' ), $attachments );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  }
159
 
160
  private function get_template( $template ) {
2
 
3
  final class ITSEC_Mail {
4
  private $content = '';
5
+ private $subject = '';
6
+ private $recipients = array();
7
+ private $attachments = array();
8
  private $template_path = '';
9
 
10
  public function __construct() {
130
  }
131
 
132
  public function add_lockouts_summary( $user_count, $host_count ) {
133
+ $lockouts = $this->get_template( 'lockouts-summary.html' );
134
 
135
  $replacements = array(
136
  'users_text' => esc_html__( 'Users', 'better-wp-security' ),
152
  $this->content .= $module;
153
  }
154
 
155
+ public function add_lockouts_table( $lockouts ) {
156
+ $entry = $this->get_template( 'lockouts-entry.html' );
157
+ $entries = '';
158
+
159
+ foreach ( $lockouts as $lockout ) {
160
+ if ( 'user' === $lockout['type'] ) {
161
+ /* translators: 1: Username */
162
+ $lockout['description'] = sprintf( wp_kses( __( '<b>User:</b> %1$s', 'better-wp-security' ), array( 'b' => array() ) ), $lockout['id'] );
163
+ } else {
164
+ /* translators: 1: Hostname */
165
+ $lockout['description'] = sprintf( wp_kses( __( '<b>Host:</b> %1$s', 'better-wp-security' ), array( 'b' => array() ) ), $lockout['id'] );
166
+ }
167
+
168
+ $entries .= $this->replace_all( $entry, $lockout );
169
+ }
170
+
171
+ $table = $this->get_template( 'lockouts-table.html' );
172
+
173
+ $replacements = array(
174
+ 'heading_types' => __( 'Host/User', 'better-wp-security' ),
175
+ 'heading_until' => __( 'Lockout in Effect Until', 'better-wp-security' ),
176
+ 'heading_reason' => __( 'Reason', 'better-wp-security' ),
177
+ 'entries' => $entries,
178
+ );
179
+
180
+ $table = $this->replace_all( $table, $replacements );
181
+
182
+ $this->content .= $table;
183
+ }
184
+
185
  public function get_content() {
186
  return $this->content;
187
  }
188
 
189
+ public function set_subject( $subject, $add_site_url = true ) {
190
+ if ( $add_site_url ) {
191
+ /* translators: 1: site URL, 2: email subject */
192
+ $subject = sprintf( __( '[%1$s] %2$s', 'better-wp-security' ), get_option( 'siteurl' ), $subject );
193
+ }
194
+
195
+ $this->subject = esc_html( $subject );
196
+ }
197
+
198
+ public function set_recipients( $recipients ) {
199
+ $this->recipients = array();
200
+
201
+ foreach ( (array) $recipients as $recipient ) {
202
+ $recipient = trim( $recipient );
203
+
204
+ if ( is_email( $recipient ) ) {
205
+ $this->recipients[] = $recipient;
206
+ }
207
+ }
208
+ }
209
+
210
+ public function set_default_recipients() {
211
+ $recipients = ITSEC_Modules::get_setting( 'global', 'notification_email' );
212
+ $this->set_recipients( $recipients );
213
+ }
214
+
215
+ public function set_attachments( $attachments ) {
216
+ $this->attachments = $attachments;
217
+ }
218
+
219
+ public function add_attachment( $attachment ) {
220
+ $this->attachments[] = $attachment;
221
+ }
222
+
223
+ public function send() {
224
+ if ( empty( $this->recipients ) ) {
225
+ $this->set_default_recipients();
226
+ }
227
+
228
+ if ( empty( $this->subject ) ) {
229
+ $this->set_default_subject();
230
+ }
231
+
232
+ return wp_mail( $this->recipients, $this->subject, $this->content, array( 'Content-Type: text/html; charset=UTF-8' ), $this->attachments );
233
  }
234
 
235
  private function get_template( $template ) {
core/lib/mail-templates/header.html CHANGED
@@ -46,9 +46,14 @@
46
  .section-heading .container-cell{padding-bottom:0;}
47
  .section-heading h4{color:#0084CB;font-size:16px;}
48
  .section-heading h4 img{padding-top:2px;padding-right:5px;vertical-align:top;}
49
- .lockouts-table .container.left-column{margin-right:60px;}
50
- .lockouts-table h4{color:#ACAAAA;font-size:16px;font-weight:normal;}
51
- .lockouts-table p{color:#505050;font-size:30px;font-weight:bold;}
 
 
 
 
 
52
  .large-text h4{color:#505050;margin-bottom:10px;}
53
  .details-box-container{padding-top:20px;padding-bottom:20px;}
54
  .details-box{background-color:#E4EEF7;border:1px solid #CDCECE;}
@@ -78,7 +83,7 @@
78
  #main-container, .container{width:100% !important;}
79
  .preserve-ratio{height:auto !important;width:100% !important;}
80
  .container-cell-bottom{padding-top:20px !important;}
81
- .lockouts-table .container{width:auto !important;}
82
  }
83
 
84
  @media only screen and (max-width:450px){
46
  .section-heading .container-cell{padding-bottom:0;}
47
  .section-heading h4{color:#0084CB;font-size:16px;}
48
  .section-heading h4 img{padding-top:2px;padding-right:5px;vertical-align:top;}
49
+ .lockouts-summary .container.left-column{margin-right:60px;}
50
+ .lockouts-summary h4{color:#ACAAAA;font-size:16px;font-weight:normal;}
51
+ .lockouts-summary p{color:#505050;font-size:30px;font-weight:bold;}
52
+ .lockouts-table{border:1px solid #cdcece;font-family:Helvetica;font-size:14px;}
53
+ .lockouts-table th,.lockouts-table td{border:1px solid #cdcece;padding:10px;}
54
+ .lockouts-table th{text-align:left;font-weight:bold;padding:5px 10px;}
55
+ .lockouts-table .row-label{font-style:italic;}
56
+ .lockouts-table a,.lockouts-table b{font-size:14px;}
57
  .large-text h4{color:#505050;margin-bottom:10px;}
58
  .details-box-container{padding-top:20px;padding-bottom:20px;}
59
  .details-box{background-color:#E4EEF7;border:1px solid #CDCECE;}
83
  #main-container, .container{width:100% !important;}
84
  .preserve-ratio{height:auto !important;width:100% !important;}
85
  .container-cell-bottom{padding-top:20px !important;}
86
+ .lockouts-summary .container{width:auto !important;}
87
  }
88
 
89
  @media only screen and (max-width:450px){
core/lib/mail-templates/lockouts-entry.html ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <tr>
2
+ <td class="row-label" style="font-style:italic;border:1px solid #cdcece;padding:10px;">{{ $description }}</td>
3
+ <td style="border:1px solid #cdcece;padding:10px;">{{ $until }}</td>
4
+ <td style="border:1px solid #cdcece;padding:10px;">{{ $reason }}</td>
5
+ </tr>
core/lib/mail-templates/lockouts-summary.html ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <td class="lockouts-summary" align="center" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
3
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
4
+ <tr>
5
+ <td align="center" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
6
+ <table class="container" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
7
+ <tr>
8
+ <td class="section-padding" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;padding-top: 20px;padding-right: 20px;padding-left: 20px;">
9
+ <table class="container left-column" align="left" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;margin-right: 60px;">
10
+ <tr>
11
+ <td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
12
+ <h4 style="color: #ACAAAA;font-family: Helvetica;font-size: 16px;font-weight: normal;line-height: 150%;margin: 0;padding: 0;text-align: center;">{{ $users_text }}</h4>
13
+ <p style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;font-family: Helvetica;font-size: 30px;line-height: 150%;margin-top: 10px;margin-right: 0;margin-bottom: 10px;margin-left: 0;padding: 0;text-align: center;color: #505050;font-weight: bold;">{{ $user_count }}</p>
14
+ </td>
15
+ </tr>
16
+ </table>
17
+ <table class="container right-column" align="right" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
18
+ <tr>
19
+ <td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
20
+ <h4 style="color: #ACAAAA;font-family: Helvetica;font-size: 16px;font-weight: normal;line-height: 150%;margin: 0;padding: 0;text-align: center;">{{ $hosts_text }}</h4>
21
+ <p style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;font-family: Helvetica;font-size: 30px;line-height: 150%;margin-top: 10px;margin-right: 0;margin-bottom: 10px;margin-left: 0;padding: 0;text-align: center;color: #505050;font-weight: bold;">{{ $host_count }}</p>
22
+ </td>
23
+ </tr>
24
+ </table>
25
+ </td>
26
+ </tr>
27
+ </table>
28
+ </td>
29
+ </tr>
30
+ </table>
31
+ </td>
32
+ </tr>
core/lib/mail-templates/lockouts-table.html CHANGED
@@ -1,32 +1,18 @@
 
 
 
 
 
 
1
  <tr>
2
- <td class="lockouts-table" align="center" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
3
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
4
- <tr>
5
- <td align="center" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
6
- <table class="container" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
7
- <tr>
8
- <td class="section-padding" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;padding-top: 20px;padding-right: 20px;padding-left: 20px;">
9
- <table class="container left-column" align="left" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;margin-right: 60px;">
10
- <tr>
11
- <td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
12
- <h4 style="color: #ACAAAA;font-family: Helvetica;font-size: 16px;font-weight: normal;line-height: 150%;margin: 0;padding: 0;text-align: center;">{{ $users_text }}</h4>
13
- <p style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;font-family: Helvetica;font-size: 30px;line-height: 150%;margin-top: 10px;margin-right: 0;margin-bottom: 10px;margin-left: 0;padding: 0;text-align: center;color: #505050;font-weight: bold;">{{ $user_count }}</p>
14
- </td>
15
- </tr>
16
- </table>
17
- <table class="container right-column" align="right" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
18
- <tr>
19
- <td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
20
- <h4 style="color: #ACAAAA;font-family: Helvetica;font-size: 16px;font-weight: normal;line-height: 150%;margin: 0;padding: 0;text-align: center;">{{ $hosts_text }}</h4>
21
- <p style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;font-family: Helvetica;font-size: 30px;line-height: 150%;margin-top: 10px;margin-right: 0;margin-bottom: 10px;margin-left: 0;padding: 0;text-align: center;color: #505050;font-weight: bold;">{{ $host_count }}</p>
22
- </td>
23
- </tr>
24
- </table>
25
- </td>
26
- </tr>
27
- </table>
28
- </td>
29
- </tr>
30
- </table>
31
- </td>
32
  </tr>
 
 
 
 
 
 
 
1
+ <tr>
2
+ <td align="center" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
3
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
4
+ <tr>
5
+ <td align="center" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
6
+ <table class="lockouts-table" border="0" cellpadding="0" cellspacing="0" width="600" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;border:1px solid #CDCECE; font-family: Helvetica;">
7
  <tr>
8
+ <th style="text-align: left;font-weight: bold;padding:5px 10px;border:1px solid #cdcece;">{{ $heading_types }}</th>
9
+ <th style="text-align: left;font-weight: bold;padding:5px 10px;border:1px solid #cdcece;">{{ $heading_until }}</th>
10
+ <th style="text-align: left;font-weight: bold;padding:5px 10px;border:1px solid #cdcece;">{{ $heading_reason }}</th>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  </tr>
12
+ {{ $entries }}
13
+ </table>
14
+ </td>
15
+ </tr>
16
+ </table>
17
+ </td>
18
+ </tr>
core/modules/backup/class-itsec-backup.php CHANGED
@@ -225,7 +225,7 @@ class ITSEC_Backup {
225
  }
226
 
227
  if ( 2 !== $this->settings['method'] || true === $one_time ) {
228
- require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-mailer.php' );
229
  $mail = new ITSEC_Mail();
230
  $mail->add_header( esc_html__( 'Database Backup', 'better-wp-security' ), sprintf( wp_kses( __( 'Site Database Backup for <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), date_i18n( get_option( 'date_format' ) ) ) );
231
  $mail->add_info_box( esc_html__( 'Attached is the database backup file for your site.', 'better-wp-security' ), 'attachment' );
@@ -240,23 +240,17 @@ class ITSEC_Backup {
240
  $mail->add_footer();
241
 
242
 
243
- $raw_recipients = ITSEC_Modules::get_setting( 'global', 'backup_email' );
244
- $recipients = array();
245
-
246
- foreach ( $raw_recipients as $recipient ) {
247
- $recipient = trim( $recipient );
248
-
249
- if ( is_email( $recipient ) ) {
250
- $recipients[] = $recipient;
251
- }
252
- }
253
 
254
  $subject = sprintf( esc_html__( '[%s] Database Backup', 'better-wp-security' ), esc_url( network_home_url() ) );
255
  $subject = apply_filters( 'itsec_backup_email_subject', $subject );
 
256
 
257
  $attachment = array( "$dir/$file$fileext" );
 
258
 
259
- $mail_success = $mail->send( $recipients, $subject, $attachment );
260
  }
261
 
262
  if ( 1 === $this->settings['method'] ) {
225
  }
226
 
227
  if ( 2 !== $this->settings['method'] || true === $one_time ) {
228
+ require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-mail.php' );
229
  $mail = new ITSEC_Mail();
230
  $mail->add_header( esc_html__( 'Database Backup', 'better-wp-security' ), sprintf( wp_kses( __( 'Site Database Backup for <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), date_i18n( get_option( 'date_format' ) ) ) );
231
  $mail->add_info_box( esc_html__( 'Attached is the database backup file for your site.', 'better-wp-security' ), 'attachment' );
240
  $mail->add_footer();
241
 
242
 
243
+ $recipients = ITSEC_Modules::get_setting( 'global', 'backup_email' );
244
+ $mail->set_recipients( $recipients );
 
 
 
 
 
 
 
 
245
 
246
  $subject = sprintf( esc_html__( '[%s] Database Backup', 'better-wp-security' ), esc_url( network_home_url() ) );
247
  $subject = apply_filters( 'itsec_backup_email_subject', $subject );
248
+ $mail->set_subject( $subject, false );
249
 
250
  $attachment = array( "$dir/$file$fileext" );
251
+ $mail->add_attachment( $attachment );
252
 
253
+ $mail_success = $mail->send();
254
  }
255
 
256
  if ( 1 === $this->settings['method'] ) {
core/modules/global/settings-page.php CHANGED
@@ -159,7 +159,7 @@ final class ITSEC_Global_Settings_Page extends ITSEC_Module_Settings_Page {
159
  <td>
160
  <?php $form->add_text( 'lockout_period', array( 'class' => 'small-text' ) ); ?>
161
  <label for="itsec-global-lockout_period"><?php _e( 'Minutes', 'better-wp-security' ); ?></label>
162
- <p class="description"><?php _e( 'The length of time a host or user will be banned from this site after hitting the limit of bad logins.', 'better-wp-security' ); ?></p>
163
  </td>
164
  </tr>
165
  <tr>
159
  <td>
160
  <?php $form->add_text( 'lockout_period', array( 'class' => 'small-text' ) ); ?>
161
  <label for="itsec-global-lockout_period"><?php _e( 'Minutes', 'better-wp-security' ); ?></label>
162
+ <p class="description"><?php _e( 'The length of time a host or user will be banned from this site after hitting the limit of bad logins. The default setting of 15 minutes is recommended as increasing it could prevent attacking IP addresses from being added to the blacklist.', 'better-wp-security' ); ?></p>
163
  </td>
164
  </tr>
165
  <tr>
core/modules/wordpress-tweaks/class-itsec-wordpress-tweaks.php CHANGED
@@ -114,6 +114,15 @@ final class ITSEC_WordPress_Tweaks {
114
  add_action( 'template_redirect', array( $this, 'disable_unused_author_pages' ) );
115
  }
116
 
 
 
 
 
 
 
 
 
 
117
  }
118
 
119
  public function block_multiauth_attempts( $filter_val, $username, $password ) {
114
  add_action( 'template_redirect', array( $this, 'disable_unused_author_pages' ) );
115
  }
116
 
117
+ if ( $this->settings['block_tabnapping'] ) {
118
+ add_action( 'wp_enqueue_scripts', array( $this, 'add_block_tabnapping_script' ) );
119
+ add_action( 'admin_enqueue_scripts', array( $this, 'add_block_tabnapping_script' ) );
120
+ }
121
+ }
122
+
123
+ public function add_block_tabnapping_script() {
124
+ wp_enqueue_script( 'blankshield', plugins_url( 'js/blankshield/blankshield.min.js', __FILE__ ), array(), ITSEC_Core::get_plugin_build(), true );
125
+ wp_enqueue_script( 'itsec-wt-block-tabnapping', plugins_url( 'js/block-tabnapping.js', __FILE__ ), array( 'blankshield' ), ITSEC_Core::get_plugin_build(), true );
126
  }
127
 
128
  public function block_multiauth_attempts( $filter_val, $username, $password ) {
core/modules/wordpress-tweaks/js/blankshield/LICENSE ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Daniel St. Jules
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
core/modules/wordpress-tweaks/js/blankshield/blankshield.min.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * blankshield - Prevent reverse tabnabbing phishing attacks caused by _blank
3
+ *
4
+ * @version 0.6.0
5
+ * @link https://github.com/danielstjules/blankshield
6
+ * @author Daniel St. Jules <danielst.jules@gmail.com>
7
+ * @license MIT
8
+ */
9
+ !function(e){"use strict";function n(e){if("undefined"==typeof e.length)o(e,"click",t);else if("string"!=typeof e&&!(e instanceof String))for(var n=0;n<e.length;n++)o(e[n],"click",t)}function t(e){var t,o,i,d;return e=e||window.event,t=e.currentTarget||e.srcElement,i=t.getAttribute("href"),i&&(d=e.ctrlKey||e.shiftKey||e.metaKey,o=t.getAttribute("target"),d||o&&!r(o))?(n.open(i),e.preventDefault?e.preventDefault():e.returnValue=!1,!1):void 0}function o(e,n,t){var o,i;return e.addEventListener?e.addEventListener(n,t,!1):(o="on"+n,e.attachEvent?e.attachEvent(o,t):e[o]?(i=e[o],e[o]=function(){t(),i()}):e[o]=t,void 0)}function i(e,n,t){var o,i,r,d,u;return o=document.createElement("iframe"),o.style.display="none",document.body.appendChild(o),i=o.contentDocument||o.contentWindow.document,d='"'+e+'"',n&&(d+=', "'+n+'"'),t&&(d+=', "'+t+'"'),r=i.createElement("script"),r.type="text/javascript",r.text="window.parent = null; window.top = null;window.frameElement = null; var child = window.open("+d+");child.opener = null",i.body.appendChild(r),u=o.contentWindow.child,document.body.removeChild(o),u}function r(e){return"_top"===e||"_self"===e||"_parent"===e}var d=-1!==navigator.userAgent.indexOf("MSIE"),u=window.open;n.open=function(e,n,t){var o;return r(n)?u.apply(window,arguments):d?(o=u.apply(window,arguments),o.opener=null,o):i(e,n,t)},n.patch=function(){window.open=function(){return n.open.apply(this,arguments)}},"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports?module.exports=n:exports.blankshield=n),"function"==typeof define&&"object"==typeof define.amd&&define("blankshield",[],function(){return n}),e.blankshield=n}(this);
core/modules/wordpress-tweaks/js/blankshield/index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden.
core/modules/wordpress-tweaks/js/block-tabnapping.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ document.addEventListener( 'DOMContentLoaded', function() {
2
+ blankshield( document.querySelectorAll( 'a[target=_blank]' ) );
3
+ });
core/modules/wordpress-tweaks/js/index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden.
core/modules/wordpress-tweaks/settings-page.php CHANGED
@@ -13,7 +13,7 @@ final class ITSEC_WordPress_Tweaks_Settings_Page extends ITSEC_Module_Settings_P
13
  protected function render_description( $form ) {
14
 
15
  ?>
16
- <p><?php _e( 'These are advanced settings that may be utilized to further strengthen the security of your WordPress site.', 'better-wp-security' ); ?></p>
17
  <?php
18
 
19
  }
@@ -50,99 +50,107 @@ final class ITSEC_WordPress_Tweaks_Settings_Page extends ITSEC_Module_Settings_P
50
  }
51
 
52
  ?>
53
- <p><?php _e( 'Note: These settings are listed as advanced because they block common forms of attacks but they can also block legitimate plugins and themes that rely on the same techniques. When activating the settings below, we recommend enabling them one by one to test that everything on your site is still working as expected.', 'better-wp-security' ); ?></p>
54
- <p><?php _e( 'Remember, some of these settings might conflict with other plugins or themes, so test your site after enabling each setting.', 'better-wp-security' ); ?></p>
55
  <table class="form-table">
56
  <tr>
57
- <th scope="row"><label for="itsec-wordpress-tweaks-wlwmanifest_header"><?php _e( 'Windows Live Writer Header', 'better-wp-security' ); ?></label></th>
58
  <td>
59
  <?php $form->add_checkbox( 'wlwmanifest_header' ); ?>
60
- <label for="itsec-wordpress-tweaks-wlwmanifest_header"><?php _e( 'Remove the Windows Live Writer header.', 'better-wp-security' ); ?></label>
61
- <p class="description"><?php _e( 'This is not needed if you do not use Windows Live Writer or other blogging clients that rely on this file.', 'better-wp-security' ); ?></p>
62
  </td>
63
  </tr>
64
  <tr>
65
- <th scope="row"><label for="itsec-wordpress-tweaks-edituri_header"><?php _e( 'EditURI Header', 'better-wp-security' ); ?></label></th>
66
  <td>
67
  <?php $form->add_checkbox( 'edituri_header' ); ?>
68
- <label for="itsec-wordpress-tweaks-edituri_header"><?php _e( 'Remove the RSD (Really Simple Discovery) header.', 'better-wp-security' ); ?></label>
69
- <p class="description"><?php _e( 'Removes the RSD (Really Simple Discovery) header. If you don\'t integrate your blog with external XML-RPC services such as Flickr then the "RSD" function is pretty much useless to you.', 'better-wp-security' ); ?></p>
70
  </td>
71
  </tr>
72
  <tr>
73
- <th scope="row"><label for="itsec-wordpress-tweaks-comment_spam"><?php _e( 'Comment Spam', 'better-wp-security' ); ?></label></th>
74
  <td>
75
  <?php $form->add_checkbox( 'comment_spam' ); ?>
76
- <label for="itsec-wordpress-tweaks-comment_spam"><?php _e( 'Reduce Comment Spam', 'better-wp-security' ); ?></label>
77
- <p class="description"><?php _e( 'This option will cut down on comment spam by denying comments from bots with no referrer or without a user-agent identified.', 'better-wp-security' ); ?></p>
78
  </td>
79
  </tr>
80
  <tr>
81
- <th scope="row"><label for="itsec-wordpress-tweaks-file_editor"><?php _e( 'File Editor', 'better-wp-security' ); ?></label></th>
82
  <td>
83
  <?php $form->add_checkbox( 'file_editor' ); ?>
84
- <label for="itsec-wordpress-tweaks-file_editor"><?php _e( 'Disable File Editor', 'better-wp-security' ); ?></label>
85
- <p class="description"><?php _e( 'Disables the file editor for plugins and themes requiring users to have access to the file system to modify files. Once activated you will need to manually edit theme and other files using a tool other than WordPress.', 'better-wp-security' ); ?></p>
86
  </td>
87
  </tr>
88
  <tr>
89
- <th scope="row"><label for="itsec-wordpress-tweaks-disable_xmlrpc"><?php _e( 'XML-RPC', 'better-wp-security' ); ?></label></th>
90
  <td>
91
- <p><?php printf( __( 'WordPress\' XML-RPC feature allows external services to access and modify content on the site. Common example of services that make use of XML-RPC are <a href="%1$s">the Jetpack plugin</a>, <a href="%2$s">the WordPress mobile app</a>, and <a href="%3$s">pingbacks</a>. If the site does not use a service that requires XML-RPC, select the "Disable XML-RPC" setting as disabling XML-RPC prevents attackers from using the feature to attack the site.', 'better-wp-security' ), esc_url( 'https://jetpack.me/' ), esc_url( 'https://apps.wordpress.org/' ), esc_url( 'https://make.wordpress.org/support/user-manual/building-your-wordpress-community/trackbacks-and-pingbacks/#pingbacks' ) ); ?></p>
92
  <?php $form->add_select( 'disable_xmlrpc', $xmlrpc_options ); ?>
93
  <ul>
94
- <li><?php _e( '<strong>Disable XML-RPC</strong> - XML-RPC is disabled on the site. This setting is highly recommended if Jetpack, the WordPress mobile app, pingbacks, and other services that use XML-RPC are not used.', 'better-wp-security' ); ?></li>
95
- <li><?php _e( '<strong>Disable Pingbacks</strong> - Only disable pingbacks. Other XML-RPC features will work as normal. Select this setting if you require features such as Jetpack or the WordPress Mobile app.', 'better-wp-security' ); ?></li>
96
- <li><?php _e( '<strong>Enable XML-RPC</strong> - XML-RPC is fully enabled and will function as normal. Use this setting only if the site must have unrestricted use of XML-RPC.', 'better-wp-security' ); ?></li>
97
  </ul>
98
  </td>
99
  </tr>
100
  <tr>
101
- <th scope="row"><label for="itsec-wordpress-tweaks-allow_xmlrpc_multiauth"><?php _e( 'Multiple Authentication Attempts per XML-RPC Request', 'better-wp-security' ); ?></label></th>
102
  <td>
103
- <p><?php _e( 'WordPress\' XML-RPC feature allows hundreds of username and password guesses per request. Use the recommended "Block" setting below to prevent attackers from exploiting this feature.', 'better-wp-security' ); ?></p>
104
  <?php $form->add_select( 'allow_xmlrpc_multiauth', $allow_xmlrpc_multiauth_options ); ?>
105
  <ul>
106
- <li><?php _e( '<strong>Block</strong> - Blocks XML-RPC requests that contain multiple login attempts. This setting is highly recommended.', 'better-wp-security' ); ?></li>
107
- <li><?php _e( '<strong>Allow</strong> - Allows XML-RPC requests that contain multiple login attempts. Only use this setting if a service requires it.', 'better-wp-security' ); ?></li>
108
  </ul>
109
  </td>
110
  </tr>
111
  <tr>
112
- <th scope="row"><label for="itsec-wordpress-tweaks-safe_jquery"><?php _e( 'Replace jQuery With a Safe Version', 'better-wp-security' ); ?></label></th>
113
  <td>
114
  <?php if ( $jquery_version_is_safe ) : ?>
115
  <?php $form->add_checkbox( 'safe_jquery' ); ?>
116
- <label for="itsec-wordpress-tweaks-safe_jquery"><?php _e( 'Enqueue a safe version of jQuery', 'better-wp-security' ); ?></label>
117
- <p class="description"><?php _e( 'Remove the existing jQuery version used and replace it with a safe version (the version that comes default with WordPress).', 'better-wp-security' ); ?></p>
118
  <?php endif; ?>
119
 
120
  <p class="description" style="color: <?php echo esc_attr( $jquery_description_color ); ?>"><?php echo $jquery_description; ?></p>
121
- <p class="description"><?php printf( __( 'Note that this only checks the homepage of your site and only for users who are logged in. This is done intentionally to save resources. If you think this is in error <a href="%s" target="_blank" rel="noopener noreferrer">click here to check again.</a> This will open your homepage in a new window allowing the plugin to determine the version of jQuery actually being used. You can then come back here and reload this page to see your version.', 'better-wp-security' ), site_url() ); ?></p>
122
  </td>
123
  </tr>
124
  <tr>
125
- <th scope="row"><label for="itsec-wordpress-tweaks-login_errors"><?php _e( 'Login Error Messages', 'better-wp-security' ); ?></label></th>
126
  <td>
127
  <?php $form->add_checkbox( 'login_errors' ); ?>
128
- <label for="itsec-wordpress-tweaks-login_errors"><?php _e( 'Disable login error messages', 'better-wp-security' ); ?></label>
129
- <p class="description"><?php _e( 'Prevents error messages from being displayed to a user upon a failed login attempt.', 'better-wp-security' ); ?></p>
130
  </td>
131
  </tr>
132
  <tr>
133
- <th scope="row"><label for="itsec-wordpress-tweaks-force_unique_nicename"><?php _e( 'Force Unique Nickname', 'better-wp-security' ); ?></label></th>
134
  <td>
135
  <?php $form->add_checkbox( 'force_unique_nicename' ); ?>
136
- <label for="itsec-wordpress-tweaks-force_unique_nicename"><?php _e( 'Force users to choose a unique nickname', 'better-wp-security' ); ?></label>
137
- <p class="description"><?php _e( 'This forces users to choose a unique nickname when updating their profile or creating a new account which prevents bots and attackers from easily harvesting user\'s login usernames from the code on author pages. Note this does not automatically update existing users as it will affect author feed urls if used.', 'better-wp-security' ); ?></p>
138
  </td>
139
  </tr>
140
  <tr>
141
- <th scope="row"><label for="itsec-wordpress-tweaks-disable_unused_author_pages"><?php _e( 'Disable Extra User Archives', 'better-wp-security' ); ?></label></th>
142
  <td>
143
  <?php $form->add_checkbox( 'disable_unused_author_pages' ); ?>
144
- <label for="itsec-wordpress-tweaks-disable_unused_author_pages"><?php _e( 'Disables a user\'s author page if their post count is 0.', 'better-wp-security' ); ?></label>
145
- <p class="description"><?php _e( 'This makes it harder for bots to determine usernames by disabling post archives for users that don\'t post to your site.', 'better-wp-security' ); ?></p>
 
 
 
 
 
 
 
 
146
  </td>
147
  </tr>
148
  </table>
13
  protected function render_description( $form ) {
14
 
15
  ?>
16
+ <p><?php esc_html_e( 'These are advanced settings that may be utilized to further strengthen the security of your WordPress site.', 'better-wp-security' ); ?></p>
17
  <?php
18
 
19
  }
50
  }
51
 
52
  ?>
53
+ <p><?php esc_html_e( 'Note: These settings are listed as advanced because they block common forms of attacks but they can also block legitimate plugins and themes that rely on the same techniques. When activating the settings below, we recommend enabling them one by one to test that everything on your site is still working as expected.', 'better-wp-security' ); ?></p>
54
+ <p><?php esc_html_e( 'Remember, some of these settings might conflict with other plugins or themes, so test your site after enabling each setting.', 'better-wp-security' ); ?></p>
55
  <table class="form-table">
56
  <tr>
57
+ <th scope="row"><label for="itsec-wordpress-tweaks-wlwmanifest_header"><?php esc_html_e( 'Windows Live Writer Header', 'better-wp-security' ); ?></label></th>
58
  <td>
59
  <?php $form->add_checkbox( 'wlwmanifest_header' ); ?>
60
+ <label for="itsec-wordpress-tweaks-wlwmanifest_header"><?php esc_html_e( 'Remove the Windows Live Writer header.', 'better-wp-security' ); ?></label>
61
+ <p class="description"><?php esc_html_e( 'This is not needed if you do not use Windows Live Writer or other blogging clients that rely on this file.', 'better-wp-security' ); ?></p>
62
  </td>
63
  </tr>
64
  <tr>
65
+ <th scope="row"><label for="itsec-wordpress-tweaks-edituri_header"><?php esc_html_e( 'EditURI Header', 'better-wp-security' ); ?></label></th>
66
  <td>
67
  <?php $form->add_checkbox( 'edituri_header' ); ?>
68
+ <label for="itsec-wordpress-tweaks-edituri_header"><?php esc_html_e( 'Remove the RSD (Really Simple Discovery) header.', 'better-wp-security' ); ?></label>
69
+ <p class="description"><?php esc_html_e( 'Removes the RSD (Really Simple Discovery) header. If you don\'t integrate your blog with external XML-RPC services such as Flickr then the "RSD" function is pretty much useless to you.', 'better-wp-security' ); ?></p>
70
  </td>
71
  </tr>
72
  <tr>
73
+ <th scope="row"><label for="itsec-wordpress-tweaks-comment_spam"><?php esc_html_e( 'Comment Spam', 'better-wp-security' ); ?></label></th>
74
  <td>
75
  <?php $form->add_checkbox( 'comment_spam' ); ?>
76
+ <label for="itsec-wordpress-tweaks-comment_spam"><?php esc_html_e( 'Reduce Comment Spam', 'better-wp-security' ); ?></label>
77
+ <p class="description"><?php esc_html_e( 'This option will cut down on comment spam by denying comments from bots with no referrer or without a user-agent identified.', 'better-wp-security' ); ?></p>
78
  </td>
79
  </tr>
80
  <tr>
81
+ <th scope="row"><label for="itsec-wordpress-tweaks-file_editor"><?php esc_html_e( 'File Editor', 'better-wp-security' ); ?></label></th>
82
  <td>
83
  <?php $form->add_checkbox( 'file_editor' ); ?>
84
+ <label for="itsec-wordpress-tweaks-file_editor"><?php esc_html_e( 'Disable File Editor', 'better-wp-security' ); ?></label>
85
+ <p class="description"><?php esc_html_e( 'Disables the file editor for plugins and themes requiring users to have access to the file system to modify files. Once activated you will need to manually edit theme and other files using a tool other than WordPress.', 'better-wp-security' ); ?></p>
86
  </td>
87
  </tr>
88
  <tr>
89
+ <th scope="row"><label for="itsec-wordpress-tweaks-disable_xmlrpc"><?php esc_html_e( 'XML-RPC', 'better-wp-security' ); ?></label></th>
90
  <td>
91
+ <p><?php printf( wp_kses( __( 'WordPress\' XML-RPC feature allows external services to access and modify content on the site. Common example of services that make use of XML-RPC are <a href="%1$s">the Jetpack plugin</a>, <a href="%2$s">the WordPress mobile app</a>, and <a href="%3$s">pingbacks</a>. If the site does not use a service that requires XML-RPC, select the "Disable XML-RPC" setting as disabling XML-RPC prevents attackers from using the feature to attack the site.', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://jetpack.me/' ), esc_url( 'https://apps.wordpress.org/' ), esc_url( 'https://make.wordpress.org/support/user-manual/building-your-wordpress-community/trackbacks-and-pingbacks/#pingbacks' ) ); ?></p>
92
  <?php $form->add_select( 'disable_xmlrpc', $xmlrpc_options ); ?>
93
  <ul>
94
+ <li><?php echo wp_kses( __( '<strong>Disable XML-RPC</strong> - XML-RPC is disabled on the site. This setting is highly recommended if Jetpack, the WordPress mobile app, pingbacks, and other services that use XML-RPC are not used.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
95
+ <li><?php echo wp_kses( __( '<strong>Disable Pingbacks</strong> - Only disable pingbacks. Other XML-RPC features will work as normal. Select this setting if you require features such as Jetpack or the WordPress Mobile app.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
96
+ <li><?php echo wp_kses( __( '<strong>Enable XML-RPC</strong> - XML-RPC is fully enabled and will function as normal. Use this setting only if the site must have unrestricted use of XML-RPC.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
97
  </ul>
98
  </td>
99
  </tr>
100
  <tr>
101
+ <th scope="row"><label for="itsec-wordpress-tweaks-allow_xmlrpc_multiauth"><?php esc_html_e( 'Multiple Authentication Attempts per XML-RPC Request', 'better-wp-security' ); ?></label></th>
102
  <td>
103
+ <p><?php esc_html_e( 'WordPress\' XML-RPC feature allows hundreds of username and password guesses per request. Use the recommended "Block" setting below to prevent attackers from exploiting this feature.', 'better-wp-security' ); ?></p>
104
  <?php $form->add_select( 'allow_xmlrpc_multiauth', $allow_xmlrpc_multiauth_options ); ?>
105
  <ul>
106
+ <li><?php echo wp_kses( __( '<strong>Block</strong> - Blocks XML-RPC requests that contain multiple login attempts. This setting is highly recommended.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
107
+ <li><?php echo wp_kses( __( '<strong>Allow</strong> - Allows XML-RPC requests that contain multiple login attempts. Only use this setting if a service requires it.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
108
  </ul>
109
  </td>
110
  </tr>
111
  <tr>
112
+ <th scope="row"><label for="itsec-wordpress-tweaks-safe_jquery"><?php esc_html_e( 'Replace jQuery With a Safe Version', 'better-wp-security' ); ?></label></th>
113
  <td>
114
  <?php if ( $jquery_version_is_safe ) : ?>
115
  <?php $form->add_checkbox( 'safe_jquery' ); ?>
116
+ <label for="itsec-wordpress-tweaks-safe_jquery"><?php esc_html_e( 'Enqueue a safe version of jQuery', 'better-wp-security' ); ?></label>
117
+ <p class="description"><?php esc_html_e( 'Remove the existing jQuery version used and replace it with a safe version (the version that comes default with WordPress).', 'better-wp-security' ); ?></p>
118
  <?php endif; ?>
119
 
120
  <p class="description" style="color: <?php echo esc_attr( $jquery_description_color ); ?>"><?php echo $jquery_description; ?></p>
121
+ <p class="description"><?php printf( wp_kses( __( 'Note that this only checks the homepage of your site and only for users who are logged in. This is done intentionally to save resources. If you think this is in error <a href="%s" target="_blank" rel="noopener noreferrer">click here to check again</a>. This will open your homepage in a new window allowing the plugin to determine the version of jQuery actually being used. You can then come back here and reload this page to see your version.', 'better-wp-security' ), array( 'a' => array( 'href' => array(), 'target' => array(), 'rel' => array() ) ) ), site_url() ); ?></p>
122
  </td>
123
  </tr>
124
  <tr>
125
+ <th scope="row"><label for="itsec-wordpress-tweaks-login_errors"><?php esc_html_e( 'Login Error Messages', 'better-wp-security' ); ?></label></th>
126
  <td>
127
  <?php $form->add_checkbox( 'login_errors' ); ?>
128
+ <label for="itsec-wordpress-tweaks-login_errors"><?php esc_html_e( 'Disable login error messages', 'better-wp-security' ); ?></label>
129
+ <p class="description"><?php esc_html_e( 'Prevents error messages from being displayed to a user upon a failed login attempt.', 'better-wp-security' ); ?></p>
130
  </td>
131
  </tr>
132
  <tr>
133
+ <th scope="row"><label for="itsec-wordpress-tweaks-force_unique_nicename"><?php esc_html_e( 'Force Unique Nickname', 'better-wp-security' ); ?></label></th>
134
  <td>
135
  <?php $form->add_checkbox( 'force_unique_nicename' ); ?>
136
+ <label for="itsec-wordpress-tweaks-force_unique_nicename"><?php esc_html_e( 'Force users to choose a unique nickname', 'better-wp-security' ); ?></label>
137
+ <p class="description"><?php esc_html_e( 'This forces users to choose a unique nickname when updating their profile or creating a new account which prevents bots and attackers from easily harvesting user\'s login usernames from the code on author pages. Note this does not automatically update existing users as it will affect author feed urls if used.', 'better-wp-security' ); ?></p>
138
  </td>
139
  </tr>
140
  <tr>
141
+ <th scope="row"><label for="itsec-wordpress-tweaks-disable_unused_author_pages"><?php esc_html_e( 'Disable Extra User Archives', 'better-wp-security' ); ?></label></th>
142
  <td>
143
  <?php $form->add_checkbox( 'disable_unused_author_pages' ); ?>
144
+ <label for="itsec-wordpress-tweaks-disable_unused_author_pages"><?php esc_html_e( 'Disables a user\'s author page if their post count is 0.', 'better-wp-security' ); ?></label>
145
+ <p class="description"><?php esc_html_e( 'This makes it harder for bots to determine usernames by disabling post archives for users that don\'t post to your site.', 'better-wp-security' ); ?></p>
146
+ </td>
147
+ </tr>
148
+ <tr>
149
+ <th scope="row"><label for="itsec-wordpress-tweaks-block_tabnapping"><?php esc_html_e( 'Protect Against Tabnapping', 'better-wp-security' ); ?></label></th>
150
+ <td>
151
+ <?php $form->add_checkbox( 'block_tabnapping' ); ?>
152
+ <label for="itsec-wordpress-tweaks-block_tabnapping"><?php esc_html_e( 'Alter target="_blank" links to protect against tabnapping', 'better-wp-security' ); ?></label>
153
+ <p class="description"><?php printf( wp_kses( __( 'Enabling this feature helps protect visitors to this site (including logged in users) from phishing attacks launched by a linked site. Details on tabnapping via target="_blank" links can be found in <a href="%s">this article</a>.', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/' ) ); ?></p>
154
  </td>
155
  </tr>
156
  </table>
core/modules/wordpress-tweaks/settings.php CHANGED
@@ -18,6 +18,7 @@ final class ITSEC_Wordpress_Tweaks_Settings extends ITSEC_Settings {
18
  'force_unique_nicename' => false,
19
  'disable_unused_author_pages' => false,
20
  'jquery_version' => '',
 
21
  );
22
  }
23
  }
18
  'force_unique_nicename' => false,
19
  'disable_unused_author_pages' => false,
20
  'jquery_version' => '',
21
+ 'block_tabnapping' => false,
22
  );
23
  }
24
  }
core/modules/wordpress-tweaks/validator.php CHANGED
@@ -27,20 +27,21 @@ class ITSEC_WordPress_Tweaks_Validator extends ITSEC_Validator {
27
  $this->sanitize_setting( 'bool', 'login_errors', __( 'Login Error Messages', 'better-wp-security' ) );
28
  $this->sanitize_setting( 'bool', 'force_unique_nicename', __( 'Force Unique Nickname', 'better-wp-security' ) );
29
  $this->sanitize_setting( 'bool', 'disable_unused_author_pages', __( 'Disable Extra User Archives', 'better-wp-security' ) );
 
30
  }
31
-
32
  protected function validate_settings() {
33
  if ( ! $this->can_save() ) {
34
  return;
35
  }
36
-
37
-
38
  $previous_settings = ITSEC_Modules::get_settings( $this->get_id() );
39
-
40
  if ( $this->settings['file_editor'] !== $previous_settings['file_editor'] ) {
41
  ITSEC_Response::regenerate_wp_config();
42
  }
43
-
44
  if ( $this->settings['disable_xmlrpc'] !== $previous_settings['disable_xmlrpc'] || $this->settings['comment_spam'] !== $previous_settings['comment_spam'] ) {
45
  ITSEC_Response::regenerate_server_config();
46
  }
27
  $this->sanitize_setting( 'bool', 'login_errors', __( 'Login Error Messages', 'better-wp-security' ) );
28
  $this->sanitize_setting( 'bool', 'force_unique_nicename', __( 'Force Unique Nickname', 'better-wp-security' ) );
29
  $this->sanitize_setting( 'bool', 'disable_unused_author_pages', __( 'Disable Extra User Archives', 'better-wp-security' ) );
30
+ $this->sanitize_setting( 'bool', 'block_tabnapping', __( 'Protect Against Tabnapping', 'better-wp-security' ) );
31
  }
32
+
33
  protected function validate_settings() {
34
  if ( ! $this->can_save() ) {
35
  return;
36
  }
37
+
38
+
39
  $previous_settings = ITSEC_Modules::get_settings( $this->get_id() );
40
+
41
  if ( $this->settings['file_editor'] !== $previous_settings['file_editor'] ) {
42
  ITSEC_Response::regenerate_wp_config();
43
  }
44
+
45
  if ( $this->settings['disable_xmlrpc'] !== $previous_settings['disable_xmlrpc'] || $this->settings['comment_spam'] !== $previous_settings['comment_spam'] ) {
46
  ITSEC_Response::regenerate_server_config();
47
  }
history.txt CHANGED
@@ -588,3 +588,7 @@
588
  Enhancement: Strong Password Enforcement now uses a PHP port of zxcvbn to ensure that a strong password was selected.
589
  Enhancement: All links in Security that have target="_blank" now have added rel attributes to protect against tabnapping.
590
  Misc: Updated remaining ip-lookup.net links to instead link to traceip.net in keeping with other links that were previously updated to traceip.net.
 
 
 
 
588
  Enhancement: Strong Password Enforcement now uses a PHP port of zxcvbn to ensure that a strong password was selected.
589
  Enhancement: All links in Security that have target="_blank" now have added rel attributes to protect against tabnapping.
590
  Misc: Updated remaining ip-lookup.net links to instead link to traceip.net in keeping with other links that were previously updated to traceip.net.
591
+ 5.8.0 - 2016-11-29 - Chris Jean
592
+ Enhancement: Updated the lockouts notification email to a new design. This new design also cleaned up the translation strings to allow better translations.
593
+ New Feature: Added a "Protect Against Tabnapping" feature in the WordPress Tweaks section. Details of what this feature protects against can be found here: https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
594
+ Misc: Updated the description for the Lockout Period setting to indicate that the default value of 15 minutes is recommended.
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === iThemes Security (formerly Better WP Security) ===
2
  Contributors: ithemes, chrisjean, gerroald, mattdanner
3
  Tags: security, security plugin, malware, hack, secure, block, SSL, admin, htaccess, lockdown, login, protect, protection, anti virus, attack, injection, login security, maintenance, permissions, prevention, authentication, administration, password, brute force, ban, permissions, bots, user agents, xml rpc, security log
4
- Requires at least: 4.4
5
- Tested up to: 4.6.1
6
- Stable tag: 5.7.1
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -188,6 +188,11 @@ Free support may be available with the help of the community in the <a href="htt
188
 
189
  == Changelog ==
190
 
 
 
 
 
 
191
  = 5.7.1 =
192
  * Bug Fix: Remote IP is now correctly identified if the server is behind a reverse proxy that sends requests with more than one IP listed in a single header.
193
  * Bug Fix: Fixed the link for a user in the logs page so that it properly works on sites that are inside a subdirectory.
@@ -1619,5 +1624,5 @@ This release is a complete rewrite from the ground up. Special thanks to Cory Mi
1619
 
1620
  == Upgrade Notice ==
1621
 
1622
- = 5.7.1 =
1623
- Version 5.7.1 contains many bug fixes and improvements. It is recommended for all users.
1
  === iThemes Security (formerly Better WP Security) ===
2
  Contributors: ithemes, chrisjean, gerroald, mattdanner
3
  Tags: security, security plugin, malware, hack, secure, block, SSL, admin, htaccess, lockdown, login, protect, protection, anti virus, attack, injection, login security, maintenance, permissions, prevention, authentication, administration, password, brute force, ban, permissions, bots, user agents, xml rpc, security log
4
+ Requires at least: 4.5
5
+ Tested up to: 4.7
6
+ Stable tag: 5.8.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
188
 
189
  == Changelog ==
190
 
191
+ = 5.8.0 =
192
+ * Enhancement: Updated the lockouts notification email to a new design. This new design also cleaned up the translation strings to allow better translations.
193
+ * New Feature: Added a "Protect Against Tabnapping" feature in the WordPress Tweaks section. Details of what this feature protects against can be found here: https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
194
+ * Misc: Updated the description for the Lockout Period setting to indicate that the default value of 15 minutes is recommended.
195
+
196
  = 5.7.1 =
197
  * Bug Fix: Remote IP is now correctly identified if the server is behind a reverse proxy that sends requests with more than one IP listed in a single header.
198
  * Bug Fix: Fixed the link for a user in the logs page so that it properly works on sites that are inside a subdirectory.
1624
 
1625
  == Upgrade Notice ==
1626
 
1627
+ = 5.8.0 =
1628
+ Version 5.8.0 adds a new feature to protect against tabnapping. It is recommended for all users.