Multiple vulnerabilities in Sliced Invoices plugin.

The WordPress Sliced Invoices plugin, which has 6,000+ active installations, was prone to multiple vulnerabilities in version 3.8.2 and below that could lead to information disclosure and SQL injection.

Reference

A CVE ID has been requested and we’ll update this post when it is assigned.

Unauthenticated information disclosure

In “core/class-sliced.php” line 220, the export_csv_full function is registered via the admin_init hook.

$this->loader->add_action( 'admin_init', $plugin_admin, 'export_csv_full' );

This function is located in “admin/class-sliced-admin.php” lines 2452-2586:

public function export_csv_full() {

   // Do the checks
   if ( ! isset( $_POST['csv_exporter_type'] ) ) {
      return;
   }
      
   if ( $_POST['csv_exporter_type'] === 'sliced_quote' ) {
      $post_type = 'sliced_quote';
      $type = 'quote';
   } elseif ( $_POST['csv_exporter_type'] === 'sliced_invoice' ) {
      $post_type = 'sliced_invoice';
      $type = 'invoice';
   } else {
      return;
   }
...
...

It doesn’t check for capability and doesn’t have a security nonce either. An unauthenticated attacker can export all invoices and quotes, which include customers’ name, home address, email address etc.

Authenticated SQL injection and information disclosure

In “core/class-sliced.php” line 211, the duplicate_quote_invoice function is registered via the admin_action_* hook:

$this->loader->add_action( 'admin_action_duplicate_quote_invoice', $plugin_admin, 'duplicate_quote_invoice' );

The function is located in “admin/class-sliced-admin.php” lines 2143-2238 and has two issues:

  1. The function lacks capability check and a security nonce. It is used to duplicate quotes or invoices, but because the plugin does not check which type of post it duplicates and the duplicated post has the “published” status, an authenticated attacker could duplicate all posts and pages available on the blog and those that were marked as “pending”, “draft” or even “private” would have their copy with a “published” status and thus would become accessible to anyone.
  2. Line 2154, it assigns the post ID value, $_GET['post'], to the $post_id variable:
    2154 $post_id = (isset($_GET['post']) ? $_GET['post'] : $_POST['post']);
    ...
    ...
    2202 $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
    

    It is inserted in the SQL query line 2202, unchecked and unsanitized which can lead to SQLi.

Additional issues

In “core/class-sliced.php” lines 201 and 202, it registers the ajax_search_clients and ajax_search_non_clients functions via the “wp_ajax_*” hook:

$this->loader->add_action( 'wp_ajax_sliced-search-clients', $plugin_admin, 'ajax_search_clients' );
$this->loader->add_action( 'wp_ajax_sliced-search-non-clients', $plugin_admin, 'ajax_search_non_clients' );

Both functions are located in “admin/class-sliced-admin.php” (line 56 and 132). They lack capability check and security nonces. An authenticated user can search all invoices and quotes, the search result will be returned as a json-encoded string.

Timeline

The vulnerability was reported on October 08, 2019.

Recommendations

Update as soon as possible if you have version 3.8.2 or below installed.
If you are using our web application firewall for WordPress, NinjaFirewall WP Edition (free) and NinjaFirewall WP+ Edition (premium), you are protected against this vulnerability.

Stay informed about the latest vulnerabilities in WordPress plugins and themes: @nintechnet