CVE-2026-24376

WPVulnerability <= 4.2.1 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
4.2.1.1
Patched in
10d
Time to patch

Description

The WPVulnerability plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 4.2.1. 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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=4.2.1
PublishedMarch 18, 2026
Last updatedMarch 27, 2026
Affected pluginwpvulnerability

What Changed in the Fix

Changes introduced in v4.2.1.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

vulnerability_nonce` or `wpvulnerability_settings_nonce`. Wait, I'll search for the localization in the source first. `wp_localize_script( 'wpvulnerability-admin', 'wpvulnerability', ... )` Actually, looking at `wpvulnerability.php`, it loads `wpvulnerability-admin.php`. I will ins…

Show full research plan

vulnerability_nonceorwpvulnerability_settings_nonce`.

Wait, I'll search for the localization in the source first.
`wp_localize_script( 'wpvulnerability-admin', 'wpvulnerability', ... )`

Actually, looking at `wpvulnerability.php`, it loads `wpvulnerability-admin.php`.
I will instruct the agent to grep for `add_action.*wp_ajax` and `wp_create_nonce`.

*Update on Nonce*: In WP, nonces are often placed in the `_wpnonce` or `nonce` field.
I'll tell the agent to look for the nonce in the settings page.

-   Subscriber account.
-   Settings must be at default.

-   `wp option get wpvulnerability_settings` shows the modified value.

-   The CVE is about "Missing Authorization".
-   The function is likely `wpvulnerability_save_settings`.
-   The vulnerability allows a Subscriber to change settings.
-   I've provided the trace and the logic.

One final detail: The `changelog` mentions "Clear legacy WPVulnerability cron events".
And `wpvulnerability.php` calls `wpvulnerability_expired_database_data()`.
If a Subscriber can trigger `wpvulnerability_expired_database_data` and it does more than just checking time, it might be the "unauthorized action". But
Research Findings
Static analysis — not yet PoC-verified

Summary

The WPVulnerability plugin for WordPress is vulnerable to unauthorized data disclosure due to missing capability checks in its REST API permission callback. Authenticated users, including those with low privileges like Subscribers, can access sensitive site security information—such as lists of vulnerable plugins, themes, and server configurations—by authenticating with an Application Password.

Vulnerable Code

// wpvulnerability-api.php line 437
/**
 * Custom permission check for the WPVulnerability REST API.
 *
 * This function checks if the request is authenticated using an Application Password.
 *
 * @since 3.3.0
 *
 * @return bool True if authenticated, false otherwise.
 */
function wpvulnerability_rest_api_permissions_check() {
	// Check if the Authorization header is present.
	if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
		$user     = $_SERVER['PHP_AUTH_USER'];
		$password = $_SERVER['PHP_AUTH_PW'];
	} elseif ( isset( $_SERVER['HTTP_AUTHORIZATION'] ) ) {
		// Handle other ways to get the Authorization header.
		$auth_header = $_SERVER['HTTP_AUTHORIZATION'];
		if ( 0 === strpos( $auth_header, 'Basic ' ) ) {
			$auth_string = base64_decode( substr( $auth_header, 6 ) );
			list( $user, $password ) = explode( ':', $auth_string );

			// Authenticate the user using the application password.
			if ( wp_authenticate_application_password( null, $user, $password ) instanceof WP_User ) {
				return true;
			}
		}
	}
}

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/wpvulnerability/4.2.1/wpvulnerability-api.php	2025-12-17 16:39:36.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wpvulnerability/4.2.1.1/wpvulnerability-api.php	2026-01-16 13:10:58.000000000 +0000
@@ -7,6 +7,8 @@
  * @since 3.3.0
  */
 
+defined( 'ABSPATH' ) || die( 'No script kiddies please!' );
+
 /**
  * Handle the core vulnerabilities REST API request.
  *
@@ -437,7 +439,8 @@
 /**
  * Custom permission check for the WPVulnerability REST API.
  *
- * This function checks if the request is authenticated using an Application Password.
+ * This function checks if the request is authenticated using an Application Password
+ * and verifies that the user has the required capabilities to access vulnerability data.
  *
  * @since 3.3.0
  *
@@ -457,8 +460,17 @@
 			list( $user, $password ) = explode( ':', $auth_string );
 
 			// Authenticate the user using the application password.
-			if ( wp_authenticate_application_password( null, $user, $password ) instanceof WP_User ) {
-				return true;
+			$authenticated_user = wp_authenticate_application_password( null, $user, $password );
+
+			if ( $authenticated_user instanceof WP_User ) {
+				// Check if user has the required capability.
+				// For multisite, require manage_network_options.
+				// For single site, require manage_options.
+				if ( is_multisite() ) {
+					return user_can( $authenticated_user, 'manage_network_options' );
+				}
+
+				return user_can( $authenticated_user, 'manage_options' );
 			}
 		}
 	}

Exploit Outline

To exploit this vulnerability, an attacker needs a valid login for a user with any role (e.g., Subscriber). The attacker first generates a WordPress Application Password via the user's profile settings. They then perform a GET request to any of the plugin's REST API endpoints (such as /wp-json/wpvulnerability/v1/plugins, /wp-json/wpvulnerability/v1/themes, or /wp-json/wpvulnerability/v1/core) while providing the credentials in the Authorization header. Because the plugin's permissions callback only verifies that the credentials are valid but does not verify that the user has administrative privileges (manage_options), the server will return a detailed list of all detected vulnerabilities and software versions for the target site.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.