Hustle <= 7.8.9.2 - Unauthenticated Information Exposure
Description
The Hustle – Email Marketing, Lead Generation, Optins, Popups plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 7.8.9.2. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=7.8.9.2What Changed in the Fix
Changes introduced in v7.8.9.3
Source Code
WordPress.org SVN# Research Plan: CVE-2026-24998 - Hustle Unauthenticated Information Exposure ## 1. Vulnerability Summary The Hustle plugin (versions <= 7.8.9.2) is vulnerable to **Sensitive Information Exposure**. This vulnerability allows unauthenticated users to extract sensitive configuration data, specificall…
Show full research plan
Research Plan: CVE-2026-24998 - Hustle Unauthenticated Information Exposure
1. Vulnerability Summary
The Hustle plugin (versions <= 7.8.9.2) is vulnerable to Sensitive Information Exposure. This vulnerability allows unauthenticated users to extract sensitive configuration data, specifically including reCaptcha secret keys and integration API keys. The exposure occurs because the plugin localizes comprehensive settings and module configuration objects into the frontend HTML via wp_localize_script, failing to sanitize or strip sensitive credentials before they are sent to the client.
2. Attack Vector Analysis
- Endpoint: Any public-facing WordPress page where a Hustle module (popup, slide-in, or embed) is active.
- Payload: A simple GET request to the site's frontend.
- Authentication: None (Unauthenticated).
- Preconditions:
- A Hustle module must be created and published.
- Sensitive data must be configured (e.g., reCaptcha secret keys in global settings or Mailchimp/Zapier API keys in module integrations).
3. Code Flow
- Settings Storage: Settings are stored in the WordPress database (typically in the
wp_optionstable under keys likehustle_settings). - Frontend Initialization: When a page loads, the plugin's frontend display logic (often handled by a class like
Hustle_Front_DisplayorHustle_Init) gathers the necessary data
Summary
The Hustle plugin for WordPress fails to properly sanitize configuration objects before localizing them for use in frontend scripts. This allows unauthenticated attackers to view sensitive credentials, such as reCaptcha secret keys and third-party integration API keys, by simply inspecting the HTML source code of any page where a Hustle module is active.
Vulnerable Code
// The vulnerability exists in the frontend initialization logic (typically in a display class) // where the plugin localizes the entire settings array to the client side without stripping sensitive keys. // Example logic based on research: $settings = get_option( 'hustle_settings' ); // ... wp_localize_script( 'hustle-front-scripts', 'hustle_data', $settings );
Security Fix
@@ -1 +1 @@ -!function(){var e={146:function(e,t,i){var s=i(5842),n=i(5413);Hustle.define("Settings.View",function(e,t,i){"use strict";const a="_page_hustle_settings";if(a!==pagenow.substr(pagenow.length-21))return;new(Backbone.View.extend({el:".sui-wrap-hustle",events:{"click .sui-sidenav .sui-vertical-tab a":"sidenav","click a.hustle-open-tab":"sidenav","change select.sui-mobile-nav":"sidenavMobile","click .sui-pagination-wrap > button":"pagination","click .hustle-load-on-click":"addLoadingState","click .hustle-settings-save":"handleSave","submit form.sui-box-body":"preventSubmit"},initialize(){const t=Hustle.get("Settings.reCaptcha_Settings"),s=Hustle.get("Settings.Top_Metrics_View"),n=Hustle.get("Settings.Privacy_Settings"),a=Hustle.get("Settings.Permissions_View"),o=Hustle.get("Settings.Data_Settings"),l=Hustle.get("Settings.Palettes");this.recaptchaView=new t,new s,new n,new a,new o,new l,e(i).off("popstate",e=>this.tabUpdate(e)),e(i).on("popstate",e=>this.tabUpdate(e)),Hustle.Events.trigger("view.rendered",this),this.doActionsBasedOnUrl()},doActionsBasedOnUrl(){if(s.getUrlParam("show-notice")){const e="success"===s.getUrlParam("show-notice")?"success":"error",t=s.getUrlParam("notice"),i=t&&"undefined"!==optinVars.messages[t]?optinVars.messages[t]:s.getUrlParam("notice-message");void 0!==i&&i.length&&n.Notification.open(e,i)}else s.getUrlParam("404-downgrade-modal")&&this.$("#hustle-dialog--404-downgrade").length&&SUI.openModal("hustle-dialog--404-downgrade","hustle-popup-number")},sidenav(t){const i=e(t.target).data("tab");i&&this.tabJump(i,!0),t.preventDefault()},sidenavMobile(t){const i=e(t.currentTarget).val();i&&this.tabJump(i,!0)},tabUpdate(e){const t=e.originalEvent.state;t&&this.tabJump(t.tabSelected)},tabJump(e,t){const i=this.$el.find('a[data-tab="'+e+'"]'),s=i.closest(".sui-vertical-tabs").find(".sui-vertical-tab"),n=this.$el.find(".sui-box[data-tab]"),a=this.$el.find('.sui-box[data-tab="'+e+'"]');t&&history.pushState({tabSelected:e},"Hustle Settings","admin.php?page=hustle_settings§ion="+e),s.removeClass("current"),n.hide(),i.parent().addClass("current"),a.show()},pagination(e){const t=this.$(e.target).closest(".sui-pagination-wrap"),i=t.find(".sui-button-icon"),s=t.next(".sui-pagination-filter");i.toggleClass("sui-active"),s.toggleClass("sui-open"),e.preventDefault(),e.stopPropagation()},preventSubmit(e){e.preventDefault()},handleSave(t){t.preventDefault();const i=this,s=e(t.currentTarget),a=s.data("form-id"),o=s.data();let l=new FormData;if(tinyMCE.triggerSave(),void 0!==a){const t=e("#"+a);t.length&&(l=new FormData(t[0]),e.each(t.find("input[type=checkbox]"),function(){const t=e(this);t.is(":checked")||l.append(t.attr("name"),"0")}))}e.each(o,(e,t)=>l.append(e,t)),l.append("_ajax_nonce",optinVars.current.save_settings_nonce),l.append("action","hustle_save_settings"),s.addClass("sui-button-onload"),s.prop("disabled",!0),e.ajax({url:ajaxurl,type:"POST",data:l,contentType:!1,processData:!1}).done(t=>{t.data?(t.data.callback&&"undefined"!==i[t.data.callback]&&i[t.data.callback](s,t.data,t.success),t.data.url?!0===t.data.url?location.reload():location.replace(t.data.url):t.data.notification&&n.Notification.open(t.data.notification.status,t.data.notification.message,t.data.notification.delay),t.data.url||(e(".sui-button-onload").removeClass("sui-button-onload"),s.prop("disabled",!1))):(t.success?n.Notification.open("success",optinVars.messages.settings_saved):n.Notification.open("error",optinVars.messages.something_went_wrong_reload),e(".sui-button-onload").removeClass("sui-button-onload"),s.prop("disabled",!1))}).fail(()=>{e(".sui-button-onload").removeClass("sui-button-onload"),s.prop("disabled",!1),n.Notification.open("error",optinVars.messages.something_went_wrong)})},actionSaveRecaptcha(){this.recaptchaView.maybeRenderRecaptchas()},addLoadingState(t){e(t.currentTarget).addClass("sui-button-onload")}}))})}
Exploit Outline
To exploit this vulnerability, an unauthenticated attacker performs a simple GET request to any public-facing page where a Hustle module (popup, slide-in, or embed) is active. By inspecting the HTML source code of the response, the attacker searches for localized JavaScript objects such as 'hustleVars' or 'optinVars' created via wp_localize_script. These objects contain the plugin's full configuration, including sensitive plaintext credentials like Google reCaptcha secret keys and API keys for integrations like Mailchimp or Zapier, which can then be used to perform unauthorized actions on those third-party services.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.