27 Aug

Our Security Review for WordPress Plugins Would Have Identified the Vulnerability in Bold Page Builder Before It Was Exploited

Last week we discussed how the developers of the Wordfence Security plugin are selling their Wordfence Premium service as being able to do something that it can’t and they don’t even try to accomplish. One of the claims about it is this:

Stay a Step Ahead of Attackers with Real-time Threat Intelligence

If your website is mission-critical you can’t afford the downtime, reputation challenges or SEO impact of getting hacked. That’s why so many sites rely on the real-time protection provided by Wordfence Premium.

In reality they are adding claimed protection against vulnerabilities after they have already been widely exploited, which is too late for the widely exploited vulnerabilities and does nothing for the vast majority of vulnerabilities that are not widely exploited, but could be used in a targeted attack.

At the end of that post we noted the real way to get ahead of hackers if you have a mission critical website is to have the security of the software you use reviewed. With WordPress websites the most important software to get reviewed would usually be the plugins being used.

To give everyone a better idea of how that can protect against vulnerabilities let’s take a look at a vulnerability that was reported to be being exploited before it was fixed last week.

Last Friday NinTechNet vaguely disclosed that a persistent cross-site scripting (XSS) vulnerability in the plugin Bold Page Builder was being exploited. Shortly after they had done that we had provided our customers with more detailed information on it, which led to additional related security vulnerabilities being fixed in the code.

As is the case with many of the widely exploited vulnerabilities in recent times the checks we do during our security reviews of WordPress plugins would have spotted the vulnerable code during multiple of the checks done, in this case five different checks.

The vulnerability starts with a function, bt_bb_save_custom_css(), which was registered to be accessible through WordPress AJAX functionality to those logged in as well as those not logged in:

327
328
add_action( 'wp_ajax_bt_bb_save_custom_css', 'bt_bb_save_custom_css' );
add_action( 'wp_ajax_nopriv_bt_bb_save_custom_css', 'bt_bb_save_custom_css' );

That means it would be checked as part of us checking any AJAX accessible functions:

Security issues with functions accessible through WordPress’ AJAX functionality (those have and continued to be a common source of disclosed vulnerabilities)

If it wasn’t already checked for that it would be checked as part of our check of any issues flagged our Plugin Security Checker, since it flags functions registered to be accessible through WordPress AJAX functionality to those logged in as well as those not logged in:

Any additional possible issues identified by our Plugin Security Checker

The function doesn’t contain much code, but it has multiple issues, which if we somehow missed during our review of the function as part of the AJAX check, would be identified by others:

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 function bt_bb_save_custom_css() {
	$post_id = intval( $_POST['post_id'] );
	$css = $_POST['css'];
	$opt_arr = get_option( 'bt_bb_custom_css' );
	if ( ! is_array( $opt_arr ) ) {
		$opt_arr = array();
	}
	if ( $css != '' ) {
		$opt_arr[ $post_id ] = $css;
	} else {
		unset( $opt_arr[ $post_id ] );
	}
	update_option( 'bt_bb_custom_css', $opt_arr );
	echo 'ok';
	die();
}

Before the main code runs in that there should be a check for a valid nonce to prevent cross-site request forgery (CSRF), which if we hadn’t looked at the code first we should have noticed when we check for that type of issue on admin pages since the function is called from there:

Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin

Next up, in the second line of code in the function user input is set to a variable without sanitization or validation. That would have been checked due to our check for reflected cross-site scripting (XSS), which in practice also is a more general check of user input being brought in to the plugin:

Reflected cross-site scripting (XSS) vulnerabilities

The final check that would involve directly checking that function’s code is that we check all usage of the function update_option(), since as is the case here, it is frequently involved in vulnerabilities being widely exploited these days:

Security issues with usage of add_option(), delete_option(), and update_option()

Through that function malicious JavaScript code could be saved a WordPress option. Through another function, bt_bb_wp_head(), that would be output on frontend pages of the website. The combination of all that would be something we checked on through another of the checks:

Persistent cross-site scripting (XSS) vulnerabilities in the frontend portions of the plugin and in the admin portions accessible to users with the Author role or below

So all total there were five checks that would have come in to play with, making it impossible that we could have missed the vulnerability. Even a lower quality security review should have caught this, which gets to the important thing to understand even if you don’t have a mission critical website, which is that most plugins haven’t gone through any sort of security review and just getting that done could greatly improve the security of WordPress websites. What certainly isn’t helping that happen is security companies like Wordfence, whose business models are not based on improving the security of WordPress websites, but profiting off them remaining insecure or even creating fake threats.