CVE-2023-6980: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: The WP SMS – Messaging & SMS Notification for WordPress, WooCommerce, GravityForms, etc plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 6.5. This is due to missing or incorrect nonce validation on the 'delete' action of the wp-sms-subscribers page. This makes it possible for unauthenticated attackers to delete subscribers via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 4.3
Published: 2024-01-03T06:15Z
Repository: https://github.com/wp-sms/wp-sms
Language: PHP
Files changed: includes/admin/subscribers/class-wpsms-subscribers-table.php
Commit date: 2023-12-23 17:28:59 +0400
Commit message: Add nonce to delete subscriber action

Diff: diff --git a/includes/admin/subscribers/class-wpsms-subscribers-table.php b/includes/admin/subscribers/class-wpsms-subscribers-table.php
index 71f2ae90..6f7839dc 100644
--- a/includes/admin/subscribers/class-wpsms-subscribers-table.php
+++ b/includes/admin/subscribers/class-wpsms-subscribers-table.php
@@ -66,16 +66,17 @@ class Subscribers_List_Table extends \WP_List_Table
     public function column_name($item)
     {
         /**
          * Sanitize the input
          */
-        $page = sanitize_text_field($_REQUEST['page']);
+        $page  = sanitize_text_field($_REQUEST['page']);
+        $nonce = wp_create_nonce('wp_sms_subscriber');
 
         //Build row actions
         $actions = array(
             'edit'   => sprintf('<a href="#" onclick="wp_sms_edit_subscriber(%s)">' . __('Edit', 'wp-sms') . '</a>', $item['ID']),
-            'delete' => sprintf('<a href="?page=%s&action=%s&ID=%s">' . __('Delete', 'wp-sms') . '</a>', $page, 'delete', $item['ID']),
+            'delete' => sprintf('<a href="%s">' . __('Delete', 'wp-sms') . '</a>', add_query_arg(array('page' => $page, 'action' => 'delete', 'ID' => $item['ID'], '_wpnonce' => $nonce), '')),
         );
 
         //Return the title contents
         return sprintf('%1$s %3$s',
             /*$1%s*/
@@ -190,10 +191,15 @@ class Subscribers_List_Table extends \WP_List_Table
             \WP_SMS\Helper::flashNotice(__('Items removed.', 'wp-sms'), 'success', $this->adminUrl);
         }
 
         // Single delete action
         if ('delete' == $current_action) {
+            if (!wp_verify_nonce($_REQUEST['_wpnonce'], 'wp_sms_subscriber')) {
+                \WP_SMS\Helper::flashNotice(__('Nonce check failed', 'wp-sms'), 'error', $this->adminUrl);
+                exit;
+            }
+
             $get_id = sanitize_text_field($_GET['ID']);
             $this->db->delete($this->tb_prefix . "sms_subscribes", ['ID' => intval($get_id)], ['%d']);
             $this->data  = $this->get_data();
             $this->count = $this->get_total();
             \WP_SMS\Helper::flashNotice(__('Item removed.', 'wp-sms'), 'success', $this->adminUrl);

Vulnerable code:         $page = sanitize_text_field($_REQUEST['page']);
            'delete' => sprintf('<a href="?page=%s&action=%s&ID=%s">' . __('Delete', 'wp-sms') . '</a>', $page, 'delete', $item['ID']),
Fixed code:         $page  = sanitize_text_field($_REQUEST['page']);
        $nonce = wp_create_nonce('wp_sms_subscriber');
            'delete' => sprintf('<a href="%s">' . __('Delete', 'wp-sms') . '</a>', add_query_arg(array('page' => $page, 'action' => 'delete', 'ID' => $item['ID'], '_wpnonce' => $nonce), '')),
            if (!wp_verify_nonce($_REQUEST['_wpnonce'], 'wp_sms_subscriber')) {
                \WP_SMS\Helper::flashNotice(__('Nonce check failed', 'wp-sms'), 'error', $this->adminUrl);
                exit;
            }