06 Dec

WordPress Plugin Security Review: Classic Editor

Recently we mentioned we are long overdue reviewing the security of the WordPress plugins we use, so here is the start of that. We start with a plugin that we didn’t expect to have any issues, but considering how many websites have started using it recently as well, it seems like a good place to start. That plugin being the Classic Editor, which “restores the previous WordPress editor and the Edit Post screen and makes it possible to use the plugins that extend it, add old-style meta boxes, or otherwise depend on the previous editor” and now has 600,000+ installations according to wordpress.org.

If you want a security review of plugins you use, when you become a paying customer of our service you can start suggesting and voting on plugins to get security reviews from us. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service. Through the end of the year you can get a free security review of a plugin or theme when you protect 100 websites with our service.

The review was done on version 0.5 of Classic Editor. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Security issues with usage of add_option(), delete_option(), and update_option()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites
  • Any additional possible issues identified by our Plugin Security Checker

Results

We found no issues with any of the checked items in version 0.5 of Classic Editor.

06 Dec

WordPress Plugin Security Review: WP Email Delivery

For our 21st security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin WP Email Delivery.

If you are not yet a customer of the service, once you sign up for the service as a paying customer you can start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 1.1.2.7 of WP Email Delivery. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Security issues with usage of add_option(), delete_option(), and update_option()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites
  • Any additional possible issues identified by our Plugin Security Checker

Results

We found two relatively minor issues. We notified the developer of the issue a week ago, but we haven’t heard back from them and no changes have been made to the plugin yet.

Test Email Sending

The plugin has functionality for sending a test email, which is intended to be sent by logged in Administrators, seeing as the frontend for that is plugin’s admin page, which is accessible only to uses with the “manage_options” capability that only Administrators normally have. The code that handles the request for that though is accessible to anyone even if they are not logged in.

Checking if a request to do that is handled in the function register_settings():

414
415
416
if(isset( $_POST[ $this->base .'test_email' ] )){
	$this->send_test_email();	
}

That function runs during admin_init, which will run when accessing the right page even if someone is not logged in:

48
add_action( 'admin_init' , array( $this, 'register_settings' ) );

The functions that handle the sending of the test email, starting with send_test_email(), don’t do any security checks, so they don’t limit who can send the test email.

What makes this of limited use for abuse is that the only user specified part of the email is the email address that it is being sent, so it couldn’t be abused to spend spam.

Lack of Protection Against Direct Access to PHP Files

Two .php files, /includes/misc-functions.php and /includes/legacy/wped.wp-mail.php, in the plugin are not intended to be directly accessed but do not contain protection against direct access. In one of them nothing runs when accessing it directly because it only defines functions and the other it hits a fatal error when trying to run the first line of code, so there is nothing exploitable if they are accessed. Other files in the plugin do contain protection against that.

03 Dec

WordPress Plugin Security Review: Conditional CAPTCHA

For our 20th security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin Conditional CAPTCHA.

If you are not yet a customer of the service, once you sign up for the service as a paying customer you can start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 4.0.0 of Conditional CAPTCHA. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Security issues with usage of add_option(), delete_option(), and update_option()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites
  • Any additional possible issues identified by our Plugin Security Checker

Results

We found one issue, it is not something we check for as part of the review, but we noticed it when checking for reflected cross-site scripting (XSS) vulnerabilities. We notified the developer of the issue a week ago, but we haven’t heard back from them and no changes have been made to the plugin yet.

Arbitrary Comment Approval

In the plugin’s code that handles what do if the CAPTCHA is entered correctly, the code will take an action with the comment specified by the plugin’s settings. One option is to approve the comment. The problem with this comes from the fact that the code as shown below, takes the action against with a comment specified by user input, the POST input “trashed_id”, and doesn’t actually check if the comment the action is being taken with is the one that lead to the CAPTCHA being shown, so this can be abused to, for example, approve any comment that was previously intentionally trashed.

318
319
320
321
if( $stored = get_comment( $_POST['trashed_id'] ) ) {
	// change status. this will call wp_notify_postauthor if set to approve
	// note, newer versions of Akismet will not register a false positive just from the status transition, because it explicitly checks to make sure the change was not made by a plugin
	wp_set_comment_status( $stored->comment_ID, $this->options['pass_action'] );
14 Sep

WordPress Plugin Security Review: Regenerate Thumbnails

For our nineteenth security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin Regenerate Thumbnails.

If you are not yet a customer of the service you can currently sign up for the service for half off and then start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins  (now accessible through a WordPress plugin of its own) to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 3.0.2 of Regenerate Thumbnails. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites
  • Any additional possible issues identified by our Plugin Security Checker

Results

We found one really minor issue.

Lack of Protection Against Direct Access to PHP Files

Two .php files in the plugin are not intended to be directly accessed but do not contain protection against direct access. The files only define classes, so there is nothing exploitable if they are accessed and adding a restriction has limited value.

13 Jul

WordPress Plugin Security Review: Stagehand Events

We were recently hired to do a security review of the WordPress plugin Stagehand Events.

The review was done on version 1.0.5 of Stagehand Events. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites
  • Any additional possible issues identified by our Plugin Security Checker

Results

We found no issues with any of the checked items in version 1.0.5 of Stagehand Events.

19 Jan

WordPress Plugin Security Review: Simple 301 Redirects

For our nineteenth security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin Simple 301 Redirects.

If you are not yet a customer of the service you can currently sign up for the service for half off and then start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins  (now accessible through a WordPress plugin of its own) to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 1.07 of Simple 301 Redirects. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of plugins
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites

Results

We found one really minor issue.

Lack of Protection Against Direct Access to PHP Files

The only .php file in the plugin is not intended to be directly accessed but does not contain protection against direct access. When the plugin is active the file will run whenever WordPress is loading, so the lack of protection against direct access doesn’t matter. If the plugin is not active then accessing the file will cause its code to run, but it will hit fatal error before anything of importance is run, so there doesn’t look to be any security issue that could be caused by this.

18 Jan

WordPress Plugin Security Review: HTTP Headers

For our eighteenth security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin HTTP Headers.

If you are not yet a customer of the service you can currently sign up for the service for half off and then start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins  (now accessible through a WordPress plugin of its own) to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 1.8.0 of HTTP Headers. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of plugins
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites

Results

We found several issues during our review.

Admin_init

We recently added a number of new checks to our reviews. One of those is to check any functions that are registered to run during “admin_init”. There are a couple of connected reasons for that. The first being that functions that are set to run then can even run when request is coming from someone that is not logged in, which is something that some of the developers using it seem to not be aware of. Even if that wasn’t true, since they run for anyone logged in, there could still be issues if something was only meant to be accessible to higher level users. The second is that because of those things, functions running then have been the source of vulnerabilities, including a zero-day vulnerability that was exploited in August in a plugin’s code to save its settings.

This plugin registers the function http_headers_admin() to run during admin_init:

813
add_action('admin_init', 'http_headers_admin');

That function first registers quite a few settings, starting with this one:

480
register_setting('http-headers-mtd', 'hh_method');

That is fine. The rest of the code is where there was a problem, as a number of actions can be taken by anyone since the only thing needed to cause them to run is including several URL parameters with a request:

565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
# When method is changed
if (isset($_GET['settings-updated'], $_GET['tab']) && $_GET['settings-updated'] == 'true' && $_GET['tab'] == 'advanced') {
	update_headers_directives();
 
	update_auth_credentials();
	update_auth_directives();
 
	update_content_encoding_directives();
 
	update_expires_directives();
 
	update_cookie_security_directives();
 
	update_timing_directives();
}
 
# When particular header is changed
if (isset($_GET['settings-updated'], $_GET['header'])
	&& $_GET['settings-updated'] == 'true'
	&& get_option('hh_method') == 'htaccess') {
 
	switch ($_GET['header']) {
		case 'www-authenticate':
			update_auth_credentials();
			update_auth_directives();
			break;
		case 'content-encoding':
		case 'vary':
			update_content_encoding_directives();
			break;
		case 'expires':
			update_expires_directives();
			break;
		case 'cookie-security':
			update_cookie_security_directives();
			break;
		case 'timing-allow-origin':
			update_timing_directives();
			break;
		default:
			update_headers_directives();
	}
}

What was interesting about this code is that it didn’t appear to be used.

Server Side Request Forgery (SSRF)

One the things that we have checked for since the first of these reviews is for a lack of protection against cross-site request forgery (CSRF) in the admin portion of plugins. CSRF is a type of vulnerability in which an attacker can cause someone else to take an action they are allowed to, but didn’t intend to. In looking into instances where the protection is missing or broken we sometimes run into larger issues. In the case of the plugin we found the “Inspect headers” tool on the plugin’s admin page not only lacked protection against CSRF, but also was accessible to anyone by making a request directly to the file, /views/ajax.php, the results for the tool come from.

With that tool you can make a request to other websites through the server, the only limit that you can only make request to URLs that begin http:// or https:// (so you couldn’t say make a request to a FTP address):

10
if (!(isset($_POST['url']) && preg_match('|^https?://|', $_POST['url'])))

That is referred to as server side request forgery (SSRF) vulnerability. Part of the risk of that is that it would allow an attacker to make requests to URLs that are accessible to the server, but not directly to the attacker, say another system that the server connects locally.

Lack of Protection Against Direct Access to Files

The plugin’s .php files lacked code at the beginning of the files to restrict direct access to them.  Beyond the SSRF issue, we didn’t see anything that could be exploited in the files without the restriction in place.

Security Issues Now Mostly Resolved

While reviewing plugins is usually fairly easy if you have experience with what is being checked on, getting the developer to properly fix the issue isn’t necessarily. In this case it took a couple of releases for the issues to be mostly resolved.

For the issue involving admin_init, in version 1.9.2 the relevant code was moved to a new function http_headers_option() that runs when the actions “added_option” and “updated_option” occur. In version 1.9.4 protection against CSRF was added for that.

For the SSRF issue the code in file /views/ajax.php was removed in version 1.9.4. In version 1.9.2 the code had been copied to a new /views/ajax-inspect.php, which can be accessed through WordPress’ AJAX functionality. In version 1.9.2 when accessing it through AJAX there was protection against CSRF added and in version 1.9.4 a capabilities check was added. The file /views/ajax-inspect.php can be accessed directly for some reason, but that file includes a file /includes/config.inc.php, which first runs code that is intended to block direct access to the file and has the additional impact of causing /views/ajax-inspect.php to stop running before getting to anything of importance.

With the exception of the file just mentioned related to the SSRF vulnerability and the related /includes/http.class.php, the plugin’s files received protection against direct access in version 1.9.2.

Proof of Concept for SSRF

The following proof concept will make a request to the homepage of our website.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-content/plugins/http-headers/views/ajax.php" method="POST">
<input type="hidden" name="do" value="inspect" />
<input type="hidden" name="url" value="https://www.pluginvulnerabilities.com" />
<input type="submit" value="Submit" />
</form>
</body>
05 Dec

WordPress Plugin Security Review: Amazon Web Services

For our sixteenth security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin Amazon Web Services.

If you are not yet a customer of the service you can currently sign up for the service for half off and then start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our new tool for doing limited automated security checks of plugins to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 1.0.4 of Amazon Web Services. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of plugins
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites

Results

During the review we only found one minor issue:

Lack of Protection Against Direct Access to Files

Numerous .php files that look like they are not intended to be accessed directly are lacking code at the beginning of the file to restrict direct access to the files. Most of the files only define classes, so there is nothing exploitable if they are accessed and adding a restriction has limited value. Other files though generate parts of admin pages and code will run when those are accessed. While in this case there was nothing that looks like a security issue due to that, in recent times we have added new vulnerabilities to our date set that were caused by files of that type where limiting access would have lessened the risk of the vulnerabilities.

20 Nov

WordPress Plugin Security Review: Nav Menu Roles

For our fifteenth security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin Nav Menu Roles.

If you are not yet a customer of the service you can currently sign up for the service for half off and then start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our new tool for doing limited automated security checks of plugins to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 1.9.1 of Nav Menu Roles. It has been a few months since we last did a review and in that time we have added six additional items that we check on during the review. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in publicly accessible portions of the plugin
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of plugins
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites

Results

During the review we only found one minor issue:

Lack of Protection Against Direct Access to Files

Three of the five .php files in the plugin lack code at the beginning of the file to restrict direct access to the files. As those three files only define classes, there is nothing exploitable due to that.