Commit 0610c4bf07 for woocommerce
commit 0610c4bf07cb3ec4ee4d2c67c1079188ca15a4a9
Author: Lucio Giannotta <lucio.giannotta@a8c.com>
Date: Wed Feb 25 06:41:35 2026 +0100
Enhance AJAX security for product and term ordering (#63422)
- Added nonce verification for product and term ordering AJAX requests to improve security.
- Updated JavaScript files to include nonce parameters in AJAX calls.
This change ensures that only authorized users can perform ordering actions.
diff --git a/plugins/woocommerce/changelog/63422-wooplug-6340-missing-nonce-validation-in-woocommerce-admin-ajax-ordering b/plugins/woocommerce/changelog/63422-wooplug-6340-missing-nonce-validation-in-woocommerce-admin-ajax-ordering
new file mode 100644
index 0000000000..9e48425f61
--- /dev/null
+++ b/plugins/woocommerce/changelog/63422-wooplug-6340-missing-nonce-validation-in-woocommerce-admin-ajax-ordering
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Add nonce verification to `product_ordering` and `term_ordering` AJAX handlers to prevent CSRF.
\ No newline at end of file
diff --git a/plugins/woocommerce/client/legacy/js/admin/product-ordering.js b/plugins/woocommerce/client/legacy/js/admin/product-ordering.js
index b6e358d20e..6df42f0166 100644
--- a/plugins/woocommerce/client/legacy/js/admin/product-ordering.js
+++ b/plugins/woocommerce/client/legacy/js/admin/product-ordering.js
@@ -1,4 +1,4 @@
-/*global ajaxurl */
+/*global ajaxurl, woocommerce_product_ordering_params */
/**
* Based on Simple Page Ordering by 10up (https://wordpress.org/plugins/simple-page-ordering/)
@@ -46,7 +46,13 @@ jQuery( function( $ ) {
// Go do the sorting stuff via ajax
$.post(
ajaxurl,
- { action: 'woocommerce_product_ordering', id: postid, previd: prevpostid, nextid: nextpostid },
+ {
+ action: 'woocommerce_product_ordering',
+ security: woocommerce_product_ordering_params.nonce,
+ id: postid,
+ previd: prevpostid,
+ nextid: nextpostid,
+ },
function( response ) {
$.each( response, function( key, value ) {
$( '#inline_' + key + ' .menu_order' ).html( value );
diff --git a/plugins/woocommerce/client/legacy/js/admin/term-ordering.js b/plugins/woocommerce/client/legacy/js/admin/term-ordering.js
index 50d9459427..1736b6cf89 100644
--- a/plugins/woocommerce/client/legacy/js/admin/term-ordering.js
+++ b/plugins/woocommerce/client/legacy/js/admin/term-ordering.js
@@ -119,6 +119,7 @@ jQuery( function( $ ) {
ajaxurl,
{
action: 'woocommerce_term_ordering',
+ security: woocommerce_term_ordering_params.nonce,
id: termid,
nextid: nexttermid,
thetaxonomy: woocommerce_term_ordering_params.taxonomy
diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-assets.php b/plugins/woocommerce/includes/admin/class-wc-admin-assets.php
index 69a1251345..f91a7e812d 100644
--- a/plugins/woocommerce/includes/admin/class-wc-admin-assets.php
+++ b/plugins/woocommerce/includes/admin/class-wc-admin-assets.php
@@ -675,6 +675,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
$woocommerce_term_order_params = array(
'taxonomy' => $taxonomy,
+ 'nonce' => wp_create_nonce( 'term-ordering' ),
);
wp_localize_script( 'woocommerce_term_ordering', 'woocommerce_term_ordering_params', $woocommerce_term_order_params );
@@ -685,6 +686,12 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
if ( current_user_can( 'edit_others_pages' ) && 'edit-product' === $screen_id && isset( $wp_query->query['orderby'] ) && 'menu_order title' === $wp_query->query['orderby'] ) {
wp_register_script( 'woocommerce_product_ordering', WC()->plugin_url() . '/assets/js/admin/product-ordering' . $suffix . '.js', array( 'jquery-ui-sortable' ), $version, true );
wp_enqueue_script( 'woocommerce_product_ordering' );
+
+ wp_localize_script(
+ 'woocommerce_product_ordering',
+ 'woocommerce_product_ordering_params',
+ array( 'nonce' => wp_create_nonce( 'product-ordering' ) )
+ );
}
// Reports Pages.
diff --git a/plugins/woocommerce/includes/class-wc-ajax.php b/plugins/woocommerce/includes/class-wc-ajax.php
index 626b9e6771..625d73e1cb 100644
--- a/plugins/woocommerce/includes/class-wc-ajax.php
+++ b/plugins/woocommerce/includes/class-wc-ajax.php
@@ -2204,7 +2204,8 @@ class WC_AJAX {
* @return void
*/
public static function term_ordering() {
- // phpcs:disable WordPress.Security.NonceVerification.Missing
+ check_ajax_referer( 'term-ordering', 'security' );
+
if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) {
wp_die( -1 );
}
@@ -2227,7 +2228,6 @@ class WC_AJAX {
echo 'children';
wp_die();
}
- // phpcs:enable
}
/**
@@ -2240,7 +2240,8 @@ class WC_AJAX {
public static function product_ordering() {
global $wpdb;
- // phpcs:disable WordPress.Security.NonceVerification.Missing
+ check_ajax_referer( 'product-ordering', 'security' );
+
if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) {
wp_die( -1 );
}
@@ -2293,7 +2294,6 @@ class WC_AJAX {
do_action( 'woocommerce_after_product_ordering', $sorting_id, $menu_orders );
wp_send_json( $menu_orders );
- // phpcs:enable
}
/**