Popup Builder <= 1.1.37 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Plugin Settings Reset
Description
The Popup Builder (Easy Notify Lite) plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the easynotify_cp_reset() function in all versions up to, and including, 1.1.37. This makes it possible for authenticated attackers, with Subscriber-level access and above, to reset plugin settings to their default values.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:LTechnical Details
<=1.1.37Source Code
WordPress.org SVNPatched version not available.
# Research Plan: CVE-2025-14446 - Popup Builder (Easy Notify Lite) Arbitrary Settings Reset ## 1. Vulnerability Summary The **Popup Builder (Easy Notify Lite)** plugin for WordPress is vulnerable to **Missing Authorization** in versions up to and including 1.1.37. The vulnerability exists within th…
Show full research plan
Research Plan: CVE-2025-14446 - Popup Builder (Easy Notify Lite) Arbitrary Settings Reset
1. Vulnerability Summary
The Popup Builder (Easy Notify Lite) plugin for WordPress is vulnerable to Missing Authorization in versions up to and including 1.1.37. The vulnerability exists within the easynotify_cp_reset() function. Because this function is hooked to a broad action (likely admin_init) without a capability check (e.g., current_user_can('manage_options')) or a valid/enforced nonce check, authenticated users with Subscriber-level permissions or higher can trigger the function to reset the plugin's settings to their default values.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin.phpor any admin page (e.g.,/wp-admin/index.php,/wp-admin/profile.php). - Trigger: An HTTP GET or POST request containing a specific trigger parameter (inferred:
easynotify_cp_resetorreset). - Authentication: Authenticated (Subscriber-level or higher).
- Preconditions: The plugin must be active. The attacker needs a valid session cookie for a Subscriber user.
3. Code Flow (Inferred)
- Hook Registration: The plugin likely registers the reset handler in the main plugin file or an admin controller:
add_action('admin_init', 'easynotify_cp_reset'); - Entry Point: When any authenticated user (including a Subscriber) accesses a page in the
/wp-admin/directory, theadmin_inithook fires. - Vulnerable Function: The
easynotify_cp_reset()function is executed. - Logic Check: The function checks for the presence of a specific request parameter:
function easynotify_cp_reset() { if ( isset( $_GET['easynotify_cp_reset'] ) ) { // Parameter name (inferred) // Missing: if ( ! current_user_can( 'manage_options' ) ) return; // Missing: check_admin_referer( 'easynotify_reset_action' ); // Logic to reset settings update_option( 'easynotify_options', $default_settings ); } } - Sink: The
update_optionordelete_optionfunction is called, overwriting the legitimate configuration with defaults.
4. Nonce Acquisition Strategy
Based on the "Missing Authorization" description, it is highly probable that either:
- No nonce check is performed at all.
- A nonce is checked but is available to Subscriber-level users in the admin dashboard.
To identify the nonce (if required):
- Search the source code for
easynotify_cp_resetto see ifcheck_admin_refererorwp_verify_nonceis called. - If a nonce is needed, search for where that nonce is created:
wp_create_nonce( '...' ). - If the nonce is created on a page accessible to Subscribers (like the Profile page or the Dashboard), use
browser_evalto extract it.
Note: If the function is hooked to admin_init and lacks a capability check, the reset might be triggered simply by appending the parameter to a URL.
5. Exploitation Strategy
The goal is to reset the plugin settings using a Subscriber account.
- Log in as Subscriber: Use the
http_requesttool to obtain a session cookie for a Subscriber user. - Identify Trigger Parameter: Grep the plugin source for the
easynotify_cp_resetfunction definition to find the exact$_GETor$_POSTparameter it listens for (e.g.,reset,easynotify_reset,easynotify_cp_reset). - Execute Reset: Send a GET request to
/wp-admin/with the trigger parameter.
Payload Example (Inferred):
GET /wp-admin/index.php?easynotify_cp_reset=1 HTTP/1.1
Host: localhost
Cookie: [Subscriber Cookies]
6. Test Data Setup
- Install Plugin: Ensure
easy-notify-liteversion 1.1.37 is installed and active. - Modify Settings: Use WP-CLI to change a plugin setting from its default to a custom value to verify the reset:
wp option update easynotify_options '{"custom_text":"Vulnerable_State"}'(Note: Option nameeasynotify_optionsis inferred and should be verified). - Create Subscriber:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
7. Expected Results
- The server responds with a 200 OK (or a 302 redirect).
- The plugin's configuration option in the
wp_optionstable is reverted to its default value (or deleted if that is the reset mechanism). - Any active notifications/popups configured by the admin disappear or revert to default text/behavior.
8. Verification Steps
After sending the exploit request, verify the database state via WP-CLI:
- Check Option Value:
wp option get easynotify_options - Compare: Confirm the value no longer contains the "Vulnerable_State" string and matches the plugin's default configuration.
9. Alternative Approaches
If the admin_init approach fails:
- AJAX Handler: Check if the reset is handled via AJAX. Grep for
wp_ajax_easynotify_reset. If so, the request would target/wp-admin/admin-ajax.phpwith theactionparameter. - Menu Page Bypass: If the reset logic is tied to a specific settings page check (e.g.,
if ($_GET['page'] == 'easynotify-settings')), the Subscriber can still requestadmin.php?page=easynotify-settings&reset=1. Even if they see a "Permissions" error, theadmin_initlogic may execute before the page content is blocked.
Summary
The Popup Builder (Easy Notify Lite) plugin is vulnerable to unauthorized data modification due to a missing capability check in the easynotify_cp_reset() function. This allows authenticated users with Subscriber-level permissions or higher to reset the plugin's configuration to its default values.
Vulnerable Code
// File: easy-notify-lite.php (or similar admin handler) // Function likely hooked to admin_init function easynotify_cp_reset() { if ( isset( $_GET['easynotify_cp_reset'] ) ) { // Vulnerability: Missing current_user_can() check // Vulnerability: Missing nonce verification $default_settings = easynotify_get_default_settings(); update_option( 'easynotify_options', $default_settings ); } }
Security Fix
@@ -10,7 +10,13 @@ function easynotify_cp_reset() { - if ( isset( $_GET['easynotify_cp_reset'] ) ) { + if ( isset( $_GET['easynotify_cp_reset'] ) ) { + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); + } + + check_admin_referer( 'easynotify_reset_action', 'easynotify_nonce' ); + $default_settings = easynotify_get_default_settings(); update_option( 'easynotify_options', $default_settings ); } }
Exploit Outline
To exploit this vulnerability, an attacker first authenticates as a Subscriber-level user on the target WordPress site. Since the vulnerable function is hooked to admin_init, it executes whenever an authenticated user accesses the administration dashboard. The attacker sends a GET request to any admin page (e.g., /wp-admin/index.php) appended with the trigger parameter identified in the code (e.g., ?easynotify_cp_reset=1). Because the plugin fails to verify the user's capabilities or check for a security nonce, the backend logic executes the reset routine, overwriting the site's notification and popup settings with the plugin's default configuration.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.