Commit 8313f0e32f9 for woocommerce
commit 8313f0e32f9d98e86ca70c5bce89b325d161b91f
Author: Liam Sarsfield <43409125+LiamSarsfield@users.noreply.github.com>
Date: Mon Aug 10 14:04:56 2026 +0100
[Order Review] Render `review-order` shortcode only on managed page and require order key (#67542)
Co-authored-by: Jorge Torres <jorge.torres@automattic.com>
diff --git a/plugins/woocommerce/changelog/fix-order-review-shortcode-key-check b/plugins/woocommerce/changelog/fix-order-review-shortcode-key-check
new file mode 100644
index 00000000000..1c21b87deff
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-order-review-shortcode-key-check
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Tighten authorization checks on the review-order shortcode.
diff --git a/plugins/woocommerce/src/Internal/OrderReviews/Endpoint.php b/plugins/woocommerce/src/Internal/OrderReviews/Endpoint.php
index f1779b5ff6a..beb17c2d3ff 100644
--- a/plugins/woocommerce/src/Internal/OrderReviews/Endpoint.php
+++ b/plugins/woocommerce/src/Internal/OrderReviews/Endpoint.php
@@ -524,23 +524,27 @@ class Endpoint {
* Render the Review Order page body for the WC-managed page.
*
* Called by `the_content` on the page that hosts `[woocommerce_review_order]`.
- * Returns an empty string when the request did not arrive through the
- * tokenised rewrite, so a logged-in admin previewing the page directly
- * sees nothing rather than a partial form.
+ * Confirms the current page and order key before rendering.
*
* @return string
*/
public function render_shortcode(): string {
global $wp;
+ $page_id = (int) wc_get_page_id( self::PAGE_KEY );
+ if ( $page_id <= 0 || ! is_page( $page_id ) ) {
+ return '';
+ }
+
if ( ! isset( $wp->query_vars[ self::QUERY_VAR ] ) ) {
return '';
}
- $order_id = absint( $wp->query_vars[ self::QUERY_VAR ] );
- $order = $order_id ? wc_get_order( $order_id ) : false;
- if ( ! $order instanceof WC_Order ) {
- // gate_request() will already have 404'd; this is defensive.
+ $order_id = absint( $wp->query_vars[ self::QUERY_VAR ] );
+ $order_key = $this->read_order_key();
+ $order = $order_id ? wc_get_order( $order_id ) : false;
+
+ if ( ! $this->is_authorised( $order, $order_key ) ) {
return '';
}
diff --git a/plugins/woocommerce/tests/php/src/Internal/OrderReviews/EndpointTest.php b/plugins/woocommerce/tests/php/src/Internal/OrderReviews/EndpointTest.php
index d54b15922d4..c7ba925f1a2 100644
--- a/plugins/woocommerce/tests/php/src/Internal/OrderReviews/EndpointTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/OrderReviews/EndpointTest.php
@@ -220,6 +220,44 @@ class EndpointTest extends WC_Unit_Test_Case {
$this->assertStringContainsString( 'Order #' . $order->get_order_number(), $html );
}
+ /**
+ * @testdox render_shortcode() only renders on the managed page with a matching order key.
+ */
+ public function test_render_shortcode_requires_managed_page_and_key(): void {
+ $order = OrderHelper::create_order();
+ $order->set_status( OrderStatus::COMPLETED );
+ $order->save();
+
+ $page_id = (int) wc_get_page_id( Endpoint::PAGE_KEY );
+ $other_page_id = (int) wp_insert_post(
+ array(
+ 'post_type' => 'page',
+ 'post_status' => 'publish',
+ 'post_title' => 'Some other page',
+ )
+ );
+
+ global $wp, $wp_query;
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- test fixture.
+ $wp = new \stdClass();
+ $wp->query_vars = array( Endpoint::QUERY_VAR => (string) $order->get_id() );
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- test fixture.
+ $wp_query = new WP_Query();
+ $wp_query->is_page = true;
+
+ $wp_query->queried_object = get_post( $page_id );
+ $_GET = array( 'key' => 'wc_order_definitelywrong' );
+ $this->assertSame( '', $this->endpoint->render_shortcode(), 'Wrong key on the managed page.' );
+
+ $wp_query->queried_object = get_post( $other_page_id );
+ $_GET = array( 'key' => $order->get_order_key() );
+ $this->assertSame( '', $this->endpoint->render_shortcode(), 'Correct key off the managed page.' );
+
+ $wp_query->queried_object = get_post( $page_id );
+ $html = $this->endpoint->render_shortcode();
+ $this->assertStringContainsString( 'Order #' . $order->get_order_number(), $html, 'Correct key on the managed page.' );
+ }
+
/**
* @testdox The woocommerce_review_order_eligible_statuses filter widens the eligible set.
*/