CVE-2026-25317

Print Invoice & Delivery Notes for WooCommerce <= 5.9.0 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
6.0.0
Patched in
10d
Time to patch

Description

The Print Invoice & Delivery Notes for WooCommerce plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 5.9.0. 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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=5.9.0
PublishedMarch 18, 2026
Last updatedMarch 27, 2026

What Changed in the Fix

Changes introduced in v6.0.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-25317 (WooCommerce Delivery Notes) ## 1. Vulnerability Summary The **Print Invoice & Delivery Notes for WooCommerce** plugin (versions <= 5.9.0) contains a missing authorization vulnerability. Specifically, the plugin's administrative settings and template cus…

Show full research plan

Exploitation Research Plan: CVE-2026-25317 (WooCommerce Delivery Notes)

1. Vulnerability Summary

The Print Invoice & Delivery Notes for WooCommerce plugin (versions <= 5.9.0) contains a missing authorization vulnerability. Specifically, the plugin's administrative settings and template customization handlers (intended for shop managers) are accessible via unauthenticated AJAX or admin_init hooks without sufficient capability checks (current_user_can). This allows unauthenticated attackers to modify critical plugin options, such as the shop name, address, policies, and document template configurations.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wcdn_save_settings (General Settings) and wcdn_save_customization (Template Settings).
  • Vulnerable Parameters:
    • wcdn_general[shop_name] (Updates wcdn_custom_company_name)
    • wcdn_general[shop_address] (Updates wcdn_company_address)
    • wcdn_general[shop_complimentry_close] (Updates wcdn_personal_notes)
    • invoice, receipt, or deliverynote (Arrays containing template layout settings)
  • Authentication: None Required (PR:N).
  • Preconditions: The plugin must be active. WooCommerce orders should exist if the attacker intends to verify changes via the "Live Preview
Research Findings
Static analysis — not yet PoC-verified

Summary

The Print Invoice & Delivery Notes for WooCommerce plugin is vulnerable to unauthorized access and data modification because it lacks capability checks on administrative AJAX handlers and order document rendering. This allows unauthenticated attackers to modify shop settings, such as the company name and address, or view sensitive order information without proper authorization.

Vulnerable Code

// includes/class-wcdn-print.php @ 5.9.0

		public function template_redirect_admin() {
			// Let the backend only access the page.
			// changed.
			if ( is_admin() && current_user_can( 'edit_shop_orders' ) && ! empty( $_REQUEST['print-order'] ) && ! empty( $_REQUEST['action'] ) ) {
				$type  = ! empty( $_REQUEST['print-order-type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['print-order-type'] ) ) : null;
				$email = ! empty( $_REQUEST['print-order-email'] ) ? sanitize_email( wp_unslash( $_REQUEST['print-order-email'] ) ) : null;

---

// includes/admin/views/Preview_template/default-preview-template.php @ 5.9.0

while ( $orders_checked < $orders_to_check && is_null( $parent_order ) ) {
		$orders = wc_get_orders(
			array(
				'limit'   => 1,
				'orderby' => 'date',
				'order'   => 'DESC',
				'offset'  => $orders_checked,
			)
		);
	if ( ! empty( $orders ) ) {
		$order = reset($orders); // phpcs:ignore
		if ( $order->get_parent_id() === 0 ) {
			$parent_order = $order;
		}
	}
		$orders_checked++;
}

Security Fix

Only in /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/6.0.0: changelog.txt
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/5.9.0/includes/admin/views/Preview_template/default-preview-template.php /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/6.0.0/includes/admin/views/Preview_template/default-preview-template.php
--- /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/5.9.0/includes/admin/views/Preview_template/default-preview-template.php	2025-09-23 10:16:22.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/6.0.0/includes/admin/views/Preview_template/default-preview-template.php	2026-01-27 07:33:04.000000000 +0000
@@ -29,12 +29,23 @@
 			$parent_order = $order;
 		}
 	}
-		$orders_checked++;
+		++$orders_checked;
 }
 if ( is_null( $parent_order ) ) {
 	echo '<div class="notices">No WooCommerce orders found! Please consider adding your first order to see this preview.</div>';
 	return;
 }
+// Ensure we always have a valid WC_Order object.
+if ( ! ( $parent_order instanceof WC_Order ) ) {
+	echo '<div class="notices">';
+	esc_html_e(
+		'No valid WooCommerce order found! Please create an order to preview this template.',
+		'woocommerce-delivery-notes'
+	);
+	echo '</div>';
+	return;
+}
+$order = $parent_order; //phpcs:ignore
 ?>
 
 	<div class="order-brandings">
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/5.9.0/includes/class-wcdn-print.php /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/6.0.0/includes/class-wcdn-print.php
--- /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/5.9.0/includes/class-wcdn-print.php	2025-05-27 08:36:38.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/woocommerce-delivery-notes/6.0.0/includes/class-wcdn-print.php	2026-01-27 07:33:04.000000000 +0000
@@ -376,7 +376,7 @@
 		 */
 		public function template_redirect_admin() {
 			// Let the backend only access the page.
-			// changed.
+			// phpcs:disable
 			if ( is_admin() && current_user_can( 'edit_shop_orders' ) && ! empty( $_REQUEST['print-order'] ) && ! empty( $_REQUEST['action'] ) ) {
 				$type  = ! empty( $_REQUEST['print-order-type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['print-order-type'] ) ) : null;
 				$email = ! empty( $_REQUEST['print-order-email'] ) ? sanitize_email( wp_unslash( $_REQUEST['print-order-email'] ) ) : null;
@@ -426,6 +426,26 @@
 				die();
 			}
 
+			/**
+			 * 🔐 ACCESS VERIFICATION
+			 */
+			foreach ( $this->order_ids as $order_id ) {
+				$order = wc_get_order( $order_id );
+				if ( ! $order ) {
+					wp_die( 'Invalid order.' );
+				}
+				if ( ! is_user_logged_in() ) {
+					$provided_token = sanitize_text_field( $_GET['guest_token'] ?? '' );
+					$saved_token    = $order->get_meta( '_guest_access_token' );
+					if ( empty( $provided_token ) || empty( $saved_token ) ) {
+						wp_die( 'Invalid or expired order link.' );
+					}
+					if ( ! hash_equals( $saved_token, $provided_token ) ) {
+						wp_die( 'Invalid or expired order link.' );
+					}
+				}
+			}
+
 			// Load the print template html.
 			$location = $this->get_template_file_location( 'print-order.php' );
 			$args     = array();

Exploit Outline

The exploit targets missing capability checks in the plugin's administrative and document-rendering functions. 1. Modification of Settings: An unauthenticated attacker can send a POST request to `/wp-admin/admin-ajax.php` using actions like `wcdn_save_settings` or `wcdn_save_customization`. By providing parameters such as `wcdn_general[shop_name]` or document layout arrays, they can overwrite the plugin's configuration, potentially injecting malicious text or redirecting customers to false contact information. 2. Unauthorized Order Access: An attacker can access sensitive customer order documents by navigating to the print endpoint (e.g., `/?print-order=ID1,ID2...`) or triggering preview templates. In vulnerable versions, the plugin fails to verify if the requester is an authorized administrator or the owner of the order (via guest tokens), allowing mass extraction of customer data and order details.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.