WooCommerce PayPal Payments <= 4.0.1 - Missing Authorization to Unauthenticated Order Manipulation and Information Disclosure
Description
The WooCommerce PayPal Payments plugin for WordPress is vulnerable to unauthorized order manipulation and information disclosure due to missing authorization checks on the `ppc-create-order` and `ppc-get-order` WC-AJAX endpoints in all versions up to, and including, 4.0.1. The `ppc-create-order` endpoint accepts an arbitrary WooCommerce order ID in the `pay-now` context without validating order ownership, allowing attackers to create PayPal orders for any WC order and write PayPal metadata to it. The `ppc-get-order` endpoint returns full PayPal order details for any PayPal order ID without binding to the requester's session. This makes it possible for unauthenticated attackers to chain these endpoints to manipulate other customers' order payment flows and exfiltrate sensitive order details (payer information, shipping data) by creating a PayPal order for a victim's WC order and then retrieving the PayPal order data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:NTechnical Details
<=4.0.1What Changed in the Fix
Changes introduced in v4.0.2
Source Code
WordPress.org SVNI cannot fulfill your request to create a detailed exploitation research plan or provide specific payloads for this vulnerability. My safety guidelines prohibit the generation of actionable exploitation materials or step-by-step guides for attacking specific software, as such information could facil…
Show full research plan
I cannot fulfill your request to create a detailed exploitation research plan or provide specific payloads for this vulnerability. My safety guidelines prohibit the generation of actionable exploitation materials or step-by-step guides for attacking specific software, as such information could facilitate unauthorized access or data exfiltration.
For security researchers and developers looking to understand or mitigate authorization vulnerabilities in WordPress plugins, I recommend consulting the following defensive resources:
- WordPress Plugin Developer Handbook: Review the sections on "User Roles and Capabilities" and "Nonces" to understand the correct implementation of
current_user_can()andcheck_ajax_referer()for protecting AJAX and REST endpoints. - OWASP Top 10: Study the "Broken Access Control" category for general principles on implementing robust authorization checks at the server side.
- WooCommerce Developer Documentation: Explore the best practices for handling order data and payment flows securely within the WooCommerce ecosystem.
- Official Patch Analysis: For educational purposes, you may examine the differences between version 4.0.1 and 4.0.2 of the WooCommerce PayPal Payments plugin on the WordPress.org SVN repository to see how the developers implemented the missing authorization checks.
Maintaining secure coding practices involves ensuring that every endpoint—especially those handling sensitive PII or financial data—validates both the intent (via nonces) and the authorization (via capability and ownership checks) of the requester.
Summary
The WooCommerce PayPal Payments plugin for WordPress (<= 4.0.1) lacks proper authorization checks on the `ppc-create-order` and `ppc-get-order` AJAX endpoints. An unauthenticated attacker can exploit this to create PayPal orders for arbitrary WooCommerce orders and subsequently retrieve sensitive customer information, including shipping addresses and PII, by querying the associated PayPal order data.
Security Fix
@@ -1,5 +1,8 @@ *** Changelog *** += 4.0.2 - 2026-04-02 = +* Fix – API rate limiting #4244 + = 4.0.1 - 2026-03-31 = * Enhancement – Removed legacy UI #4031 * Enhancement – Added migration banner guiding BCDC merchants through upgrade to Advanced Card Processing #4192 @@ -140,7 +140,10 @@ return new PayPalBearer($container->get('api.paypal-bearer-cache'), $container->get('api.host'), $container->get('api.key'), $container->get('api.secret'), $container->get('woocommerce.logger.woocommerce'), $container->get('settings.settings-provider')); }, 'api.endpoint.partners' => static function (ContainerInterface $container): PartnersEndpoint { - return new PartnersEndpoint($container->get('api.host'), $container->get('api.bearer'), $container->get('woocommerce.logger.woocommerce'), $container->get('api.factory.sellerstatus'), $container->get('api.partner_merchant_id'), $container->get('api.merchant_id'), $container->get('api.helper.failure-registry')); + return new PartnersEndpoint($container->get('api.host'), $container->get('api.bearer'), $container->get('woocommerce.logger.woocommerce'), $container->get('api.factory.sellerstatus'), $container->get('api.partner_merchant_id'), $container->get('api.merchant_id'), $container->get('api.helper.failure-registry'), $container->get('api.partners-seller-status-cache')); + }, + 'api.partners-seller-status-cache' => static function (ContainerInterface $container): Cache { + return new Cache('ppcp-seller-status-'); }, 'api.factory.sellerstatus' => static function (ContainerInterface $container): SellerStatusFactory { return new SellerStatusFactory(); ... (truncated)
Exploit Outline
An unauthenticated attacker first identifies a target WooCommerce order ID (e.g., through enumeration). They then send an unauthenticated request to the `wc-ajax=ppc-create-order` endpoint, passing the target order ID and setting the context to `pay-now`. Because the endpoint fails to verify if the current user session owns the order, it creates a new PayPal order and links it to the target WooCommerce order. The attacker captures the PayPal order ID from the response and sends a subsequent request to the `wc-ajax=ppc-get-order` endpoint. This second endpoint returns the full PayPal order details, including the victim's name, email, and shipping address, as it does not validate that the requester is the person who initiated the original order.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.