WPLegalPages <= 3.5.4 - Missing Authorization
Description
The Privacy Policy Generator, Terms & Conditions Generator WordPress Plugin : WP Legal Pages 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.4. 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
<=3.5.4What Changed in the Fix
Changes introduced in v3.5.5
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-67974 - WPLegalPages Missing Authorization ## 1. Vulnerability Summary The **WP Legal Pages** plugin (versions up to 3.5.4) contains a missing authorization vulnerability within several of its REST API endpoints. The vulnerability arises because the `permissio…
Show full research plan
Exploitation Research Plan: CVE-2025-67974 - WPLegalPages Missing Authorization
1. Vulnerability Summary
The WP Legal Pages plugin (versions up to 3.5.4) contains a missing authorization vulnerability within several of its REST API endpoints. The vulnerability arises because the permission_callback for these routes checks the plugin's global "connection" state (whether it is linked to the SaaS dashboard) rather than verifying the current user's capabilities.
Specifically, in admin/class-wp-legal-pages-admin.php, the routes registered under the wpl/v2 and appwplp/v1 namespaces use a closure that returns true if $is_user_connected is true. Since this variable is set at the time of route registration based on site settings, an unauthenticated attacker can access these endpoints once a site administrator has "connected" the plugin.
2. Attack Vector Analysis
- Endpoint:
POST /wp-json/wpl/v2/get_user_dashboard_data - Alternative Endpoint:
POST /wp-json/appwplp/v1/wplp_get_payment_status - Vulnerable Hook:
rest_api_init - Vulnerable Function:
WP_Legal_Pages_Admin::register_wpl_dashboard_route - Authentication: Unauthenticated (provided the site is "connected").
Summary
The WP Legal Pages plugin for WordPress is vulnerable to unauthorized data access due to missing capability checks in several REST API endpoints. In versions up to 3.5.4, the permission callbacks for routes like `/wpl/v2/get_user_dashboard_data` only verify if the site is connected to the plugin's SaaS dashboard, allowing unauthenticated attackers to access sensitive site information if the connection is active.
Vulnerable Code
// admin/class-wp-legal-pages-admin.php line 118 public function register_wpl_dashboard_route() { require_once plugin_dir_path( __DIR__ ) . 'includes/settings/class-wp-legal-pages-settings.php'; global $is_user_connected, $api_user_plan; // Make global variables accessible $this->settings = new WP_Legal_Pages_Settings(); $is_user_connected = $this->settings->is_connected(); register_rest_route( 'wpl/v2', // Namespace '/get_user_dashboard_data', array( 'methods' => 'POST', 'callback' => array($this, 'wplp_send_data_to_dashboard_appwplp_server'), // Function to handle the request 'permission_callback' => function() use ($is_user_connected) { // Check if user is connected and the API plan is valid if ($is_user_connected) { return true; // Allow access } return new WP_Error('rest_forbidden', 'Unauthorized access', array('status' => 401)); }, ) );
Security Fix
@@ -110,9 +175,63 @@ require_once plugin_dir_path( __DIR__ ) . 'includes/settings/class-wp-legal-pages-settings.php'; global $is_user_connected, $api_user_plan; // Make global variables accessible $this->settings = new WP_Legal_Pages_Settings(); + + $master_key = $this->settings->get('api','token'); $is_user_connected = $this->settings->is_connected(); + register_rest_route( + 'wplp-react/v1', //New namespace for React dashboard + '/get_dashboard-data', + array( + 'methods' => 'POST', + 'callback' => array($this, 'wplp_send_data_to_dashboard_appwplp_react_app'), // Function to handle the request + 'permission_callback' => function(WP_REST_Request $request) use ($master_key) { + + + $auth_header = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : ''; + if ( ! preg_match('/Bearer\s(\S+)/', $auth_header, $matches) ) { + return new WP_Error('no_token', 'Authorization token missing.', ['status' => 401]); + } + $token = sanitize_text_field($matches[1]); + + // 2. Validate token with central WP site + $validate = wp_remote_post( + 'https://app.wplegalpages.com/wp-json/jwt-auth/v1/token/validate', + [ + 'headers' => [ + 'Authorization' => 'Bearer ' . $token, + 'Content-Type' => 'application/json' + ], + 'timeout' => 15 + ] + ); + + if ( is_wp_error($validate) ) { + return new WP_Error('token_validation_failed', $validate->get_error_message(), ['status' => 401]); + } + + $code = wp_remote_retrieve_response_code($validate); + if ( $code !== 200 ) { + return new WP_Error('invalid_token', 'Token validation failed.', ['status' => 401]); + } + + // 3. Extract master_key from the request body + $body = $request->get_json_params(); + $incoming_key = isset($body['master_key']) ? sanitize_text_field($body['master_key']) : ''; + + if ( empty($incoming_key) ) { + return new WP_Error('master_key_missing', 'Master key not provided.', ['status' => 401]); + } + + if ( $master_key !== $incoming_key ) { + return new WP_Error('invalid_master_key', 'Master key mismatch.', ['status' => 401]); + } + + return true; // All good → allow callback + }, + ) + );
Exploit Outline
To exploit this vulnerability, an attacker first identifies a WordPress site using the WP Legal Pages plugin that has been 'connected' to the official SaaS service (which sets the `$is_user_connected` global to true). The attacker then sends an unauthenticated POST request to `/wp-json/wpl/v2/get_user_dashboard_data`. Because the `permission_callback` only checks the Boolean value of the plugin's connection state rather than verifying user capabilities or a secure token, the endpoint returns sensitive information including the site name, published legal pages, and internal API secrets.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.