PluginProbe
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… / 3.0.0
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… v3.0.0
3.0.0 2.11.12 2.11.11 2.11.10 2.11.9 2.11.7 2.11.8 2.11.6 2.11.5 2.11.4 2.11.3 2.11.1 2.11.2 2.11.0 2.10.5 2.10.4 2.10.3 2.10.2 2.10.1 2.10.0 2.9.9 2.9.8 2.9.6 2.9.7 2.9.5 All 88 releases
← All changes | includes/class-activity-log.php +44 -8 2.10.23.0.0 View file →
@@ -141,9 +141,9 @@
141 141 *
142 142 * Gate checks (in order):
143 143 * 1. Module master switch (modules.activity_log)
144 144 * 2. Per-type flag via $type_flag_map (types not in the map always pass)
145 - * 3. Sub-check: failed logins respect log_failed_logins
145 + * 3. Login: each of its two checkboxes governs its own half (see below)
146 146 * 4. User/IP exclusions
147 147 *
148 148 * @param string $type Event type.
149 149 * @param string $action Event action.
@@ -160,9 +160,9 @@
160 160
161 161 // Gate 2: Per-type flag
162 162 $current_options = $this->get_current_options();
163 163
164 - if ( isset( self::$type_flag_map[ $type ] ) ) {
164 + if ( isset( self::$type_flag_map[ $type ] ) && 'login' !== $type ) {
165 165 $flag = self::$type_flag_map[ $type ];
166 166 if ( empty( $current_options[ $flag ] ) ) {
167 167 return false;
168 168 }
@@ -167,11 +167,35 @@
167 167 return false;
168 168 }
169 169 }
170 170
171 - // Gate 3: Failed logins sub-check
172 - if ( 'login' === $type && in_array( $action, array( 'failed', 'lockout' ), true ) ) {
173 - if ( empty( $current_options['log_failed_logins'] ) ) {
171 + /*
172 + * Gate 3: login is the one type with two checkboxes, offered side by
173 + * side as "Successful logins" and "Failed login attempts". Until 2.11.10
174 + * the per-type gate above cut first, so unchecking the first one also
175 + * silenced the second and with it everything security relevant this type
176 + * carries: failed attempts, lockouts, logins blocked by a forced reset
177 + * and the probes of the hidden wp-admin and login. The audit alerts of
178 + * the login category went quiet at the same time, because they only fire
179 + * for events that get stored, so a site under attack looked calm on both
180 + * screens. Found by the file-by-file review of 2.11.10.
181 + *
182 + * Each checkbox governs its own half now: a successful login answers to
183 + * log_logins, and everything else about login, which is attack traffic,
184 + * answers to log_failed_logins.
185 + */
186 + if ( 'login' === $type ) {
187 + /*
188 + * Written as the list of what is attack traffic, not as "everything
189 + * that is not a success": login_url_notified is an administrative
190 + * notice and answering to the failed-attempts checkbox made it
191 + * disappear for anyone who had that one unchecked, which is a record
192 + * 2.11.9 did keep. Found by the cross review of 2.11.10.
193 + */
194 + $attack = array( 'failed', 'lockout', 'lockout_blocked', 'hidden_admin_access', 'hidden_login_access', 'force_reset_login_blocked' );
195 + $flag = in_array( $action, $attack, true ) ? 'log_failed_logins' : 'log_logins';
196 +
197 + if ( empty( $current_options[ $flag ] ) ) {
174 198 return false;
175 199 }
176 200 }
177 201
@@ -930,8 +954,14 @@
930 954 * scanner probe, and a remote manager being refused apart from an intruder,
931 955 * so an owner looking at a surprising entry had no way to tell which one
932 956 * they were reading.
933 957 *
958 + * That first sentence was not true of the firewall, which is the module
959 + * that logs the most: it stored the address under 'uri', so the column
960 + * this method feeds was empty for every one of its blocks, and diagnosing
961 + * one meant reading the table by hand. Fixed in the firewall in 2.11.1;
962 + * 'uri' is read here as well so the entries already on disk show it too.
963 + *
934 964 * @since 2.10.2
935 965 *
936 966 * @param string|array|null $extra_data The entry's extra data, as stored.
937 967 * @return string The recorded address, or '' when the entry carries none.
@@ -940,20 +970,26 @@
940 970 if ( is_string( $extra_data ) ) {
941 971 $extra_data = json_decode( $extra_data, true );
942 972 }
943 973
944 - if ( ! is_array( $extra_data ) || ! isset( $extra_data['request_uri'] ) ) {
974 + if ( ! is_array( $extra_data ) ) {
945 975 return '';
946 976 }
947 977
978 + $key = isset( $extra_data['request_uri'] ) ? 'request_uri' : 'uri';
979 +
980 + if ( ! isset( $extra_data[ $key ] ) ) {
981 + return '';
982 + }
983 +
948 984 // Nothing writes anything but a string here, but the value comes back
949 985 // from a longtext column that any past version could have filled, and
950 986 // casting an array would emit a notice and print the word "Array".
951 - if ( ! is_scalar( $extra_data['request_uri'] ) ) {
987 + if ( ! is_scalar( $extra_data[ $key ] ) ) {
952 988 return '';
953 989 }
954 990
955 - return (string) $extra_data['request_uri'];
991 + return (string) $extra_data[ $key ];
956 992 }
957 993
958 994 /**
959 995 * Cleanup old logs based on retention settings (uses fresh options)