20 Oct

Authenticated Persistent Cross-Site (XSS) Vulnerability in InPost Gallery

One of the ways we keep track of vulnerabilities in WordPress plugins to provide our customers with the best data is by monitoring our websites for apparent activity by hackers. We recently had a request for a file from the plugin InPost Gallery, /wp-content/plugins/inpost-gallery/js/front.js. We don’t have that plugin installed on the website, so the request would likely be from someone probing for usage of the plugin. In looking over the plugin for something that hackers might target, we found a couple of vulnerabilities and some additional security issues. We are not sure if either of the vulnerabilities we found are are what the hacker was looking for, or if there is still some other issue lurking in the plugin.

The lesser of the two vulnerabilities was an authenticated persistent cross-site scripting (XSS) vulnerability.

The plugin registers the function save_settings() to be accessible to anyone logged in through WordPress’ AJAX functionality (through the file /index.php):

91
add_action('wp_ajax_inpost_gallery_save_settings', array(__CLASS__, 'save_settings'));

The settings page is only accessible to users who have the “edit_pages” capability (which would normally be Editor and Administrator level users). The save_settings() function therefore should be restricted in the same way, but it wasn’t as of version 2.1.2:

155
156
157
158
159
160
161
public static function save_settings()
{
	$data = array();
	parse_str($_REQUEST['values'], $data);
	update_option('inpost_gallery_settings', $data);
	exit;
}

There also wasn’t any nonce check needed to prevent cross-site request forgery (CSRF), which also could have much the same impact as a capabilities check since the nonce shouldn’t be accessible to lower level users. You can also see that there is no sanitization done there.

When the value is echoed through the file /views/admin/settings.php to be shown on the settings page the values are not escaped. For example, the value for input “admin_thumb_width” is echoed out on line 28:

<b><?php _e("Post metabox thumbnails size", 'inpost-gallery') ?></b>:&nbsp;<input class="inpost_gallery_image_size_field" type="text" value="<?php echo $admin_thumb_width ?>" name="admin_thumb_width" />&nbsp;x&nbsp;<input class="inpost_gallery_image_size_field" type="text" value="<?php echo $admin_thumb_height ?>" name="admin_thumb_height" />&nbsp;px<br />

After we notified the developer of the issue, version 2.1.2.1 was released, which adds a capabilities check to the save_settings() function (no protection against CSRF has been added yet):

556
557
558
559
560
561
562
563
564
565
566
public static function save_settings()
{
	if (current_user_can('manage_options'))
	{
		$data = array();
		parse_str($_REQUEST['values'], $data);
		update_option('inpost_gallery_settings', $data);
	}
 
	exit;
}

Proof of Concept

The following proof of concept will cause an alert box with any accessible cookies to be shown on the page /wp-admin/options-general.php?page=inpost-gallery-settings, when logged in to WordPress.

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

http://[path to WordPress]/wp-admin/admin-ajax.php?action=inpost_gallery_save_settings&values=admin_thumb_width="><script>alert(document.cookie);</script>

Timeline

  • 10/16/2016 – Developer notified.
  • 10/18/2016- Version 2.1.2.1 released, which fixes issue.

Leave a Reply

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