Skip to content

Commit 50d0368

Browse files
committed
V2.2.5.1
1 parent bef7c76 commit 50d0368

22 files changed

+11356
-241
lines changed

defines.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
defined( 'ABSPATH' ) or die( 'Something went wrong.' );
33

4-
define( 'SECUPRESS_VERSION' , '2.2.4.1' );
4+
define( 'SECUPRESS_VERSION' , '2.2.5.1' );
55
define( 'SECUPRESS_MAJOR_VERSION' , '2.2' );
66
define( 'SECUPRESS_PATH' , realpath( dirname( SECUPRESS_FILE ) ) . DIRECTORY_SEPARATOR );
77
define( 'SECUPRESS_INC_PATH' , SECUPRESS_PATH . 'free' . DIRECTORY_SEPARATOR );

free/admin/functions/admin.php

+1-53
Original file line numberDiff line numberDiff line change
@@ -287,56 +287,4 @@ function secupress_print_pro_advantages() {
287287
</div>
288288
</div>
289289
<?php
290-
}
291-
292-
293-
/**
294-
* Retrieve messages by their ID and format them by wrapping them in `<ul>` and `<li>` tags.
295-
*
296-
* @since 1.0
297-
*
298-
* @param (array) $msgs An array of messages.
299-
* @param (string) $test_name The scanner name.
300-
*
301-
* @return (string) An HTML list of formatted messages.
302-
*/
303-
function secupress_format_message( $msgs, $test_name ) {
304-
$classname = 'SecuPress_Scan_' . $test_name;
305-
$messages = $classname::get_instance()->get_messages();
306-
307-
$output = array();
308-
309-
if ( empty( $msgs ) ) {
310-
return implode( '<br/>', $output );
311-
}
312-
313-
foreach ( $msgs as $id => $atts ) {
314-
315-
if ( ! isset( $messages[ $id ] ) ) {
316-
317-
$string = __( 'Fix done.', 'secupress' );
318-
319-
} elseif ( is_array( $messages[ $id ] ) ) {
320-
321-
$count = array_shift( $atts );
322-
$string = translate_nooped_plural( $messages[ $id ], $count );
323-
324-
} else {
325-
326-
$string = $messages[ $id ];
327-
328-
}
329-
330-
if ( $atts ) {
331-
foreach ( $atts as $i => $att ) {
332-
if ( is_array( $att ) ) {
333-
$atts[ $i ] = wp_sprintf_l( '%l', $att );
334-
}
335-
}
336-
}
337-
338-
$output[] = ! empty( $atts ) ? vsprintf( $string, $atts ) : $string;
339-
}
340-
341-
return implode( '<br/>', $output );
342-
}
290+
}

free/admin/settings.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -511,12 +511,19 @@ function secupress_scanners() {
511511
<?php _e( 'Good', 'secupress' ); ?>
512512
<span class="secupress-count-good"></span>
513513
</li>
514+
<?php if ( $counts['warning'] > 0 ) : ?>
515+
<li class="status-warning" data-status="warning">
516+
<span class="secupress-carret"></span>
517+
<?php _e( 'Pending', 'secupress' ); ?>
518+
<span class="secupress-count-warning"></span>
519+
</li>
520+
<?php endif; ?>
514521
<li class="status-bad" data-status="bad">
515522
<span class="secupress-carret"></span>
516523
<?php _e( 'Bad', 'secupress' ); ?>
517524
<span class="secupress-count-bad"></span>
518525
</li>
519-
<?php if ( $counts['notscannedyet'] ) : ?>
526+
<?php if ( $counts['notscannedyet'] > 0 ) : ?>
520527
<li class="status-notscannedyet" data-status="notscannedyet">
521528
<span class="secupress-carret"></span>
522529
<?php _e( 'New Scan', 'secupress' ); ?>

free/classes/scanners/class-secupress-scan-bad-vuln-plugins.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public static function get_messages( $message_id = null ) {
8686
104 => __( 'No plugins selected for deactivation.', 'secupress' ),
8787
105 => _n_noop( 'Selected plugin has been deactivated (but some are still there).', 'All selected plugins have been deactivated (but some are still there).', 'secupress' ),
8888
106 => _n_noop( 'Sorry, the following plugin could not be deactivated: %s.', 'Sorry, the following plugins could not be deactivated: %s.', 'secupress' ),
89+
107 => __( 'Your installation may contain vulnerable plugins. The PRO version will be more accurate.', 'secupress' ),
8990
// "bad"
9091
/** Translators: 1 is a number, 2 is a plugin name (or a list of plugin names). */
9192
200 => _n_noop( '<strong>%1$d plugin</strong> is known to be vulnerable: %2$s.', '<strong>%1$d plugins</strong> are known to be vulnerable: %2$s.', 'secupress' ),
@@ -94,7 +95,6 @@ public static function get_messages( $message_id = null ) {
9495
203 => _n_noop( 'Sorry, this plugin could not be deleted.', 'Sorry, those plugins could not be deleted.', 'secupress' ),
9596
204 => _n_noop( 'The following plugin should be deactivated if you don’t need it: %s.', 'The following plugins should be deactivated if you don’t need them: %s.', 'secupress' ),
9697
205 => _n_noop( 'Sorry, this plugin could not be deactivated.', 'Sorry, those plugins could not be deactivated.', 'secupress' ),
97-
206 => __( 'Your installation may contain vulnerable plugins. The PRO version will be more accurate.', 'secupress' ),
9898
// "cantfix"
9999
/** Translators: %d is a number. */
100100
300 => _n_noop( '<strong>%d</strong> plugin can be <strong>deleted</strong>.', '<strong>%d</strong> plugins can be <strong>deleted</strong>.', 'secupress' ),
@@ -152,7 +152,7 @@ public function scan() {
152152
$bad_plugins = $this->get_installed_plugins_vulnerables();
153153

154154
if ( is_numeric( $bad_plugins ) ) {
155-
$this->add_message( 206 );
155+
$this->add_message( 107 );
156156
} elseif ( $count = count( $bad_plugins ) ) {
157157
// "bad"
158158
$this->add_message( 200, array( $count, $count, self::wrap_in_tag( $bad_plugins ) ) );

free/classes/scanners/class-secupress-scan-discloses.php

+9
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ public function scan() {
167167

168168
if ( $has_response ) {
169169
$powered_by = wp_remote_retrieve_header( $response, 'x-powered-by' );
170+
$powered_by = is_array( $powered_by ) ? reset( $powered_by ) : $powered_by;
170171
$body = wp_remote_retrieve_body( $response );
171172
}
172173

@@ -289,6 +290,14 @@ public function fix() {
289290

290291
if ( $has_response ) {
291292
$powered_by = wp_remote_retrieve_header( $response, 'x-powered-by' );
293+
if ( is_array( $powered_by ) ) {
294+
foreach( $powered_by as $p ) {
295+
if ( strpos( $p, 'PHP/' ) === 0 ) {
296+
$powered_by = $p;
297+
break;
298+
}
299+
}
300+
}
292301
$body = wp_remote_retrieve_body( $response );
293302
}
294303

free/classes/scanners/class-secupress-scan-https.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public static function get_messages( $message_id = null ) {
148148
// "bad"
149149
200 => __( 'Your site is not totally using HTTPS/SSL: %s', 'secupress' ),
150150
201 => __( 'Your site does not use HTTPS/SSL. Error: %s', 'secupress' ),
151-
202 => __( 'Your website seems to run under maintenance mode, rescan this later when you set it off.', 'secupress' ),
151+
202 => __( 'Your website seems to run under maintenance mode, relaunch the HTTPS scanner later when you set it off.', 'secupress' ),
152152
// "cantfix"
153153
300 => __( 'Cannot be fixed automatically. You have to contact you host provider to ask him to <strong>upgrade your site with HTTPS/SSL</strong>.', 'secupress' ),
154154
301 => __( 'Update your HOME url and SITE url with <code>https://</code>.', 'secupress' ),

free/classes/settings/class-secupress-settings.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -1554,8 +1554,8 @@ protected function print_sideads() {
15541554
if ( 'secupress_ad_before' !== $sidead['hook'] ) {
15551555
continue;
15561556
}
1557-
if ( ( 'free' === $sidead['when'] && ! secupress_is_pro() )
1558-
|| ( 'pro' === $sidead['when'] && secupress_is_pro() )
1557+
if ( ( 'free' === $sidead['when'] && ! secupress_has_pro() )
1558+
|| ( 'pro' === $sidead['when'] && secupress_has_pro() )
15591559
|| 'both' === $sidead['when']
15601560
) {
15611561
$content_locale = 'content-' . get_user_locale();

free/functions/common.php

+55-3
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ function secupress_die( $message = '', $title = '', $args = array() ) {
369369
$message = '<h1>' . SECUPRESS_PLUGIN_NAME . '</h1>' . $message;
370370
$url = secupress_get_current_url( 'raw' );
371371
$force_die = ! empty( $args['force_die'] );
372+
$context = ! empty( $args['context'] ) ? $args['context'] : '';
372373
$is_scan_request = secupress_is_scan_request(); // Used to bypass the whitelist for scans.
373374

374375
/**
@@ -381,7 +382,7 @@ function secupress_die( $message = '', $title = '', $args = array() ) {
381382
* @param (array) $args Facultative arguments.
382383
* @param (bool) $is_scan_request Tell if the request comes from one of our scans.
383384
*/
384-
$message = apply_filters( 'secupress.die.message', $message, $url, $args, $is_scan_request );
385+
$message = apply_filters( 'secupress.die.message', $message, $url, $args, $is_scan_request, $context );
385386

386387
/**
387388
* Fires right before `wp_die()`.
@@ -393,7 +394,7 @@ function secupress_die( $message = '', $title = '', $args = array() ) {
393394
* @param (array) $args Facultative arguments.
394395
* @param (bool) $is_scan_request Tell if the request comes from one of our scans.
395396
*/
396-
do_action( 'secupress.before.die', $message, $url, $args, $is_scan_request );
397+
do_action( 'secupress.before.die', $message, $url, $args, $is_scan_request, $context );
397398

398399
if ( $force_die || $is_scan_request ) {
399400
// Die.
@@ -1663,9 +1664,60 @@ function secupress_status( $status ) {
16631664
$statuses = [];
16641665
$statuses['bad'] = __( 'Bad', 'secupress' );
16651666
$statuses['good'] = __( 'Good', 'secupress' );
1666-
$statuses['warning'] = __( 'Warning', 'secupress' );
1667+
$statuses['warning'] = __( 'Pending', 'secupress' );
16671668
$statuses['cantfix'] = __( 'Error', 'secupress' );
16681669

16691670
return isset( $statuses[ $status ] ) ? $statuses[ $status ] : __( 'New', 'secupress' );
16701671
}
16711672

1673+
1674+
/**
1675+
* Retrieve messages by their ID and format them by wrapping them in `<ul>` and `<li>` tags.
1676+
*
1677+
* @since 1.0
1678+
*
1679+
* @param (array) $msgs An array of messages.
1680+
* @param (string) $test_name The scanner name.
1681+
*
1682+
* @return (string) An HTML list of formatted messages.
1683+
*/
1684+
function secupress_format_message( $msgs, $test_name ) {
1685+
$classname = 'SecuPress_Scan_' . $test_name;
1686+
$messages = $classname::get_instance()->get_messages();
1687+
1688+
$output = array();
1689+
1690+
if ( empty( $msgs ) ) {
1691+
return implode( '<br/>', $output );
1692+
}
1693+
1694+
foreach ( $msgs as $id => $atts ) {
1695+
1696+
if ( ! isset( $messages[ $id ] ) ) {
1697+
1698+
$string = __( 'Fix done.', 'secupress' );
1699+
1700+
} elseif ( is_array( $messages[ $id ] ) ) {
1701+
1702+
$count = array_shift( $atts );
1703+
$string = translate_nooped_plural( $messages[ $id ], $count );
1704+
1705+
} else {
1706+
1707+
$string = $messages[ $id ];
1708+
1709+
}
1710+
1711+
if ( $atts ) {
1712+
foreach ( $atts as $i => $att ) {
1713+
if ( is_array( $att ) ) {
1714+
$atts[ $i ] = wp_sprintf_l( '%l', $att );
1715+
}
1716+
}
1717+
}
1718+
1719+
$output[] = ! empty( $atts ) ? vsprintf( $string, $atts ) : $string;
1720+
}
1721+
1722+
return implode( '<br/>', $output );
1723+
}

free/functions/ip.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function secupress_get_ip() {
3434
*
3535
* @return (bool) True is valid IP
3636
*/
37-
function secupress_ip_is_valid( $ip, $range_format = false , $flag = null ) {
37+
function secupress_ip_is_valid( $ip, $range_format = false , $flag = 0 ) {
3838
if ( ! $ip || ! is_string( $ip ) ) {
3939
return false;
4040
}
@@ -891,7 +891,7 @@ function secupress_ban_ip( $time_ban = 5, $ip = null, $die = true ) {
891891
_n( 'Your IP address %1$s has been banned for %2$s minute, please do not retry until then.', 'Your IP address %1$s has been banned for %2$s minutes, please do not retry until then.', $time_ban, 'secupress' ),
892892
'<code>' . esc_html( $ip ) . '</code>',
893893
'<strong>' . number_format_i18n( $time_ban ) . '</strong>'
894-
), array( 'force_die' => true ) );
894+
), array( 'force_die' => true, 'context' => 'ban_ip' ) );
895895
}
896896
}
897897

free/modules/antispam/plugins/fightspam.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -771,8 +771,8 @@ function secupress_fightspam_dont_comment_too_soon_timer() {
771771
if ( ! secupress_get_module_option( 'antispam_comment-delay', 1, 'antispam' ) ) {
772772
return;
773773
}
774-
// Only do this if we are on a post type page which supports comments with a non logged in user
775-
if ( is_user_logged_in() || ! get_post_type() || ! post_type_supports( get_post_type(), 'comments' ) ) {
774+
// Only do this if we are on a singular page which supports comments and where comments are open with a non logged in user
775+
if ( ! is_singular() || is_user_logged_in() || post_type_supports( get_post_type(), 'comments' ) || comments_open() ) {
776776
return;
777777
}
778778
// Set our timer in PHP with a filter

free/modules/firewall/plugins/request-methods-header.php

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@
1414
* @since 2.0 Allow all requests methods but customs and TRACE.
1515
*/
1616
$methods = array( 'GET' => true, 'POST' => true, 'HEAD' => true, 'PUT' => true, 'PATCH' => true, 'DELETE' => true, 'CONNECT' => true, 'OPTIONS' => true );
17+
if ( ! function_exists( 'is_plugin_active' ) ) {
18+
require ABSPATH . 'wp-admin/includes/plugin.php';
19+
}
20+
if ( is_plugin_active( 'matomo/matomo.php' ) && isset( $_SERVER['REQUEST_METHOD'] ) && ! array_key_exists( $_SERVER['REQUEST_METHOD'], $methods ) ) {
21+
$methods[ $_SERVER['REQUEST_METHOD'] ] = true;
22+
}
23+
/**
24+
* Filters the methods array
25+
* @param (array) $methods
26+
* @since 2.2.5
27+
* **/
28+
$methods = apply_filters( 'secupress.plugins.bbrm.methods', $methods );
1729

1830
if ( ! isset( $methods[ $_SERVER['REQUEST_METHOD'] ] ) ) {
1931
secupress_block( 'RMHM', [ 'code' => 405, 'b64' => [ 'data' => $_SERVER['REQUEST_METHOD'] ] ] );

free/modules/firewall/tools.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function secupress_firewall_bbq_host_content_bad_contents_list_default() {
5959
*/
6060
function secupress_firewall_bbq_referer_content_bad_contents_list_default() {
6161
return apply_filters( 'secupress.bad_referer_contents.list',
62-
'semalt.com, todaperfeita, ambien, blue spill, cialis, cocaine, ejaculat, erectile, erections, hoodia, huronriveracres, impotence, levitra, libido, lipitor, phentermin, sandyauer, tramadol, troyhamby, ultram, unicauca, valium, viagra, vicodin, xanax, ypxaieo'
62+
'semalt.com, todaperfeita, ambien, blue spill, cocaine, ejaculat, erectile, erections, hoodia, huronriveracres, impotence, levitra, libido, lipitor, phentermin, sandyauer, tramadol, troyhamby, ultram, unicauca, valium, viagra, vicodin, xanax, ypxaieo'
6363
);
6464
}
6565

free/modules/plugins-themes/callbacks.php

+1-11
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,7 @@ function secupress_plugins_themes_settings_callback( $settings ) {
3131
// Uploads.
3232
secupress_uploads_settings_callback( $modulenow, $activate );
3333

34-
/**
35-
* Filter the settings before saving.
36-
*
37-
* @since 1.4.9
38-
*
39-
* @param (array) $settings The module settings.
40-
* @param (array\bool) $activate Contains the activation rules for the different modules
41-
*/
42-
$settings = apply_filters( "secupress_{$modulenow}_settings_callback", $settings, $activate );
43-
44-
return $settings;
34+
return array( 'sanitized' => 1 );
4535
}
4636

4737

free/modules/users-login/plugins/limitloginattempts.php

+54-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* @return (null|object)
2222
*/
2323
function secupress_limitloginattempts( $raw_user, $username ) {
24+
global $wpdb;
2425
static $done = false;
2526

2627
if ( $done ) {
@@ -37,15 +38,66 @@ function secupress_limitloginattempts( $raw_user, $username ) {
3738
}
3839

3940
$max_attempts = secupress_get_module_option( 'login-protection_number_attempts', 10, 'users-login' );
40-
$user_attempts = (int) get_user_meta( $uid, '_secupress_limitloginattempts', true );
41+
42+
// Adding initial Value
43+
$wpdb->query(
44+
$wpdb->prepare(
45+
"
46+
INSERT INTO {$wpdb->usermeta} (user_id, meta_key, meta_value)
47+
SELECT * FROM (SELECT %d, '_secupress_limitloginattempts', 0) as tmp
48+
WHERE NOT EXISTS (
49+
SELECT * FROM {$wpdb->usermeta}
50+
WHERE user_id = %d
51+
AND meta_key = '_secupress_limitloginattempts'
52+
);
53+
",
54+
$uid,
55+
$uid
56+
)
57+
);
58+
59+
// Start transaction
60+
$wpdb->query("START TRANSACTION");
61+
62+
// Removed in 2.2.5, TOCTOU flaw
63+
// $user_attempts = (int) get_user_meta( $uid, '_secupress_limitloginattempts', true );
64+
65+
// Get the number of attempts (line lock with FOR UPDATE)
66+
$user_attempts = $wpdb->get_var(
67+
$wpdb->prepare(
68+
"
69+
SELECT meta_value FROM {$wpdb->usermeta}
70+
WHERE {$wpdb->usermeta}.meta_key = '_secupress_limitloginattempts'
71+
AND {$wpdb->usermeta}.user_id = %d
72+
LIMIT 1 FOR UPDATE
73+
",
74+
$uid
75+
)
76+
);
77+
4178
++$user_attempts;
4279

4380
if ( $user_attempts >= $max_attempts ) {
4481
delete_user_meta( $uid, '_secupress_limitloginattempts' );
4582
secupress_ban_ip( (int) secupress_get_module_option( 'login-protection_time_ban', 5, 'users-login' ) );
4683
}
4784

48-
update_user_meta( $uid, '_secupress_limitloginattempts', $user_attempts );
85+
// Removed in 2.2.5, TOCTOU flaw
86+
// update_user_meta( $uid, '_secupress_limitloginattempts', $user_attempts );
87+
88+
// Update number of attempts
89+
$wpdb->query(
90+
$wpdb->prepare(
91+
"UPDATE {$wpdb->usermeta} SET meta_value = %d WHERE user_id = %d and meta_key = '_secupress_limitloginattempts'",
92+
$user_attempts,
93+
$uid
94+
)
95+
);
96+
97+
// End transaction with a COMMIT command
98+
$wpdb->query("COMMIT");
99+
100+
49101
$user_attempts_left = $max_attempts - $user_attempts;
50102

51103
if ( $user_attempts_left <= 3 ) {

0 commit comments

Comments
 (0)