Gift Cards (Gift Vouchers and Packages) (WooCommerce Supported) <= 4.6.9 - Missing Authorization
Description
The Gift Cards (Gift Vouchers and Packages) (WooCommerce Supported) plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 4.6.9. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v4.7.0
Source Code
WordPress.org SVNnopriv_` for logged-out users. Since there is no `nopriv` registration, this is not an unauthenticated leak. So we are back to the AJAX handlers or shortcodes. The `wpgv_voucher_successful_shortcode` is definitely a "Missing Authorization" on an action (marking a voucher as paid). L…
Show full research plan
nopriv_for logged-out users. Since there is nonopriv` registration, this is not an unauthenticated leak.
So we are back to the AJAX handlers or shortcodes.
The `wpgv_voucher_successful_shortcode` is definitely a "Missing Authorization" on an action (marking a voucher as paid).
Let's focus on that as it's a very clear "Unauthorized Action".
One problem: How do we get a `voucheritem` ID?
If we can't create one via AJAX, we can just guess? They are sequential IDs.
Or we can use the "Check Voucher Balance" shortcode to find IDs?
`echo do_shortcode(' [wpgv-check-voucher-balance] ');`
Actually, let's stick to the AJAX voucher creation.
Final check on `wpgv_doajax_gift_card_pdf_save`:
The function `wpgv__doajax_gift_card_pdf_save_func` is definitely the target for the "Missing Authorization" on function.
The `nopriv` registration is inferred, but highly likely for a gift card plugin purchase flow.
1. Create a "Success" page with `[wpgv-voucher-successful]`.
2. Find/Create a "Gift Card" page with a form to get the nonce `wpgv_giftitems_form_verify`.
*Note*:
Summary
The Gift Cards plugin for WordPress fails to implement proper authorization checks in its 'payment successful' shortcode and gift card saving AJAX handlers. This allows unauthenticated attackers to mark gift card orders as 'Paid' without completing payment or to create unauthorized voucher entries by manipulating request parameters within a one-hour window of order creation.
Vulnerable Code
// include/voucher-shortcodes.php line 8 function wpgv_voucher_successful_shortcode() { global $wpdb; $return = ''; $voucher_table = $wpdb->prefix . 'giftvouchers_list'; // ... (omitted code) if (isset($_GET['voucheritem'])) { $voucheritem = absint($_GET['voucheritem']); $voucher_options = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $voucher_table WHERE id = %d", $voucheritem) ); $check_send_mail = $voucher_options->check_send_mail; if ((strtotime($voucher_options->voucheradd_time) + 3600) < strtotime(current_time('mysql'))) { return '<div class="error"><p>' . esc_html_e('This URL is invalid. You can not access this page directly.', 'gift-voucher') . '</p></div>'; } // ... (omitted code) if ($voucherrow) { $wpdb->update( $voucher_table, array( 'payment_status' => 'Paid', 'voucheradd_time' => current_time('mysql') ), array('id' => $voucheritem), array( '%s' ), array('%d') ); --- // include/wpgv_giftcard_pdf.php line 8 function wpgv__doajax_gift_card_pdf_save_func() { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized if (! isset($_POST['nonce']) || ! ! wp_verify_nonce(wp_unslash($_POST['nonce']), 'wpgv_giftitems_form_verify')) { wp_send_json_error(array('message' => 'Invalid security token')); wp_die(); } global $wpdb; $voucher_table = $wpdb->prefix . 'giftvouchers_list'; // ... (processes input and performs $wpdb->insert without capability check)
Security Fix
@@ -2,6 +2,80 @@ if (!defined('ABSPATH')) exit; // Exit if accessed directly +if (!function_exists('wpgv_is_plugin_admin_screen')) { + /** + * Check whether the current admin request belongs to this plugin's own screens. + * + * @param WP_Screen|null $screen Optional screen object. + * @return bool + */ + function wpgv_is_plugin_admin_screen($screen = null) + { + if (!is_admin()) { + return false; + } + + if (null === $screen && function_exists('get_current_screen')) { + $screen = get_current_screen(); + } + + $current_page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; + $current_post_type = isset($_GET['post_type']) ? sanitize_key(wp_unslash($_GET['post_type'])) : ''; + $current_taxonomy = isset($_GET['taxonomy']) ? sanitize_key(wp_unslash($_GET['taxonomy'])) : ''; + + $allowed_pages = array( + 'wpgv-gift-cards', + 'voucher-templates', + 'new-voucher-template', + 'view-voucher-details', + 'voucher-setting', + 'vouchers-lists', + ); + $allowed_post_types = array( + 'voucher_template', + 'wpgv_voucher_product', + ); + $allowed_taxonomies = array( + 'wpgv_voucher_category', + 'category_voucher_template', + ); + + if ($current_page && in_array($current_page, $allowed_pages, true)) { + return true; + } + + if ($current_post_type && in_array($current_post_type, $allowed_post_types, true)) { + return true; + } + + if ($current_taxonomy && in_array($current_taxonomy, $allowed_taxonomies, true)) { + return true; + } + + if (!$screen) { + return false; + } + + if (!empty($screen->post_type) && in_array($screen->post_type, $allowed_post_types, true)) { + return true; + } + + if (!empty($screen->taxonomy) && in_array($screen->taxonomy, $allowed_taxonomies, true)) { + return true; + } + + if (!empty($screen->id)) { + foreach ($allowed_pages as $allowed_page) { + if (false !== strpos($screen->id, $allowed_page)) { + return true; + } + } + } + + return false; + } +} +
Exploit Outline
The exploit targets the missing authorization in the `wpgv_voucher_successful_shortcode` function. An attacker first identifies or generates a pending gift card order (voucher item ID). They then navigate to the page containing the `[wpgv-voucher-successful]` shortcode, appending the `voucheritem` parameter with the targeted ID (e.g., `?voucheritem=123`). As long as the request is made within 3600 seconds of the voucher's creation, the plugin will update the `payment_status` to 'Paid' in the database without verifying if the current user is an admin or the legitimate payer. This results in the gift card being activated and potentially sent to a recipient without actual financial transaction completion.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.