09 Sep

NinTechnet and WordPress Plugin Directory Team Fail to Make Sure Vulnerability in Search Exclude Was Actually Fixed

Last week we disclosed a settings change vulnerability in the plugin Search Exclude after it had been closed on the WordPress Plugin Directory and noted that wasn’t the only probable issue:

There also appear to be other security issues with the plugin.

Part of what we referring to has now been disclosed by NinTechNet, but they incorrectly claim that it has been fixed, when in fact there is still a vulnerability due to only being partially fixed. The team running the WordPress Plugin Directory also missed that it hasn’t been fixed.

Here is how NinTechNet explained the issue:

Line 56, the plugin registers the saveBulkEdit function via the wp_ajax_* hook:

56
add_action('wp_ajax_search_exclude_save_bulk_edit', array($this, 'saveBulkEdit'));

The function, located lines 141-148, lacks capability check and a security nonce, allowing an authenticated user, such as a subscriber, to change the settings via WordPress AJAX API:

141
142
143
144
145
146
147
148
public function saveBulkEdit()
{
	$postIds = !empty($_POST['post_ids']) ? $_POST[ 'post_ids' ] : false;
	$exclude = isset($_POST['sep_exclude']) && '' !== $_POST['sep_exclude']  ? $_POST[ 'sep_exclude' ] : null;
	if (is_array($postIds) && null !== $exclude) {
		$this->savePostIdsToSearchExclude($postIds, $exclude);
	}
}

Elsewhere in their post they claim this has been fixed, presumably in version 1.2.3 as they state “Update as soon as possible if you have version 1.2.2 or below installed.”

They also mentioning having reported that to the team running the Plugin Directory, which seems to have caused the closure, but the plugin was re-opened without it being fully resolved.

NinTechNet doesn’t show how this was fixed, which they should have, since they likely would have realized it hasn’t been fixed if they had done that.

Here is how that function looks as of the latest version, 1.2.4:

141
142
143
144
145
146
147
148
149
150
151
public function saveBulkEdit()
{
	$this->checkPermissions();
	$postIds = !empty($_POST['post_ids']) ? $this->filterPostIds($_POST[ 'post_ids' ]) : false;
	$exclude = isset($_POST['sep_exclude']) && '' !== $_POST['sep_exclude']
		? filter_var($_POST['sep_exclude'], FILTER_VALIDATE_BOOLEAN)
		: null;
	if (is_array($postIds) && null !== $exclude) {
		$this->savePostIdsToSearchExclude($postIds, $exclude);
	}
}

Neither of the missing security checks have been added directly in that, but presumably they would be handled by the function checkPermissions() that was added.

That function only does the capability check:

319
320
321
322
323
324
325
326
private function checkPermissions()
{
	$capability = apply_filters('searchexclude_filter_permissions', 'edit_others_pages');
 
	if ( !current_user_can($capability) ) {
		wp_die( 'Not enough permissions', '', ['response' => 401, 'exit' => true] );
	}
}

So there is still a cross-site request forgery (CSRF) vulnerability due to the lack of a nonce check.

We Actually Check If Vulnerabilities Have Been Fixed

Missing that vulnerabilities haven’t been fixed has long been a problem with others involved in the security of WordPress plugins. It was just a couple of months ago Sucuri also didn’t explain how a vulnerability was fixed, which could have allowed them to see a vulnerability they were disclosing hadn’t been fixed at all.

Being told there is a vulnerability, but that it has been fixed, is of limited value. With our service we actually test things out and determine which versions of plugins are vulnerable, so our customers are warned when this type of situation happens, which is a frequent occurrence.

We also help everyone out to a lesser degree in this type of situation, as we have notified the developer of the unresolved issue.