CVE-2025-67974

WPLegalPages <= 3.5.4 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.5.5
Patched in
7d
Time to patch

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: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<=3.5.4
PublishedJanuary 27, 2026
Last updatedFebruary 2, 2026
Affected pluginwplegalpages

What Changed in the Fix

Changes introduced in v3.5.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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").
Research Findings
Static analysis — not yet PoC-verified

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

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/wplegalpages/3.5.4/admin/class-wp-legal-pages-admin.php /home/deploy/wp-safety.org/data/plugin-versions/wplegalpages/3.5.5/admin/class-wp-legal-pages-admin.php
--- /home/deploy/wp-safety.org/data/plugin-versions/wplegalpages/3.5.4/admin/class-wp-legal-pages-admin.php	2025-11-13 09:45:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wplegalpages/3.5.5/admin/class-wp-legal-pages-admin.php	2025-11-25 08:49:48.000000000 +0000
@@ -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.