HubSpot All-In-One Marketing - Forms, Popups, Live Chat <= 11.3.32 - Missing Authorization to Authenticated (Contributor+) Installed Plugin Disclosure
Description
The HubSpot All-In-One Marketing - Forms, Popups, Live Chat plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 11.3.32 via the leadin/public/admin/class-adminconstants.php file. This makes it possible for authenticated attackers, with Contributor-level access and above, to extract a list of all installed plugins and their versions which can be leveraged for reconnaissance and further attacks.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
What Changed in the Fix
Changes introduced in v11.3.33
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-11762 (HubSpot All-In-One Marketing) ## 1. Vulnerability Summary The **HubSpot All-In-One Marketing** plugin (up to 11.3.32) is vulnerable to **Sensitive Information Exposure** via the `leadin/public/admin/class-adminconstants.php` file. The plugin fails to pe…
Show full research plan
Exploitation Research Plan: CVE-2025-11762 (HubSpot All-In-One Marketing)
1. Vulnerability Summary
The HubSpot All-In-One Marketing plugin (up to 11.3.32) is vulnerable to Sensitive Information Exposure via the leadin/public/admin/class-adminconstants.php file. The plugin fails to perform adequate authorization checks on a REST API endpoint (or localized data gathering process) that provides configuration data to the admin interface. Specifically, the list of all installed plugins and their versions is gathered using get_plugins() and returned to any authenticated user with Contributor-level access or higher. This information is typically used for reconnaissance by attackers to find other vulnerable plugins.
2. Attack Vector Analysis
- Endpoint: WordPress REST API namespace
leadin/v1. - Route:
/wp-json/leadin/v1/config(inferred from plugin architecture). - Method:
GET - Authentication: Required (Contributor+ role).
- Payload: None (direct GET request).
- Preconditions: The plugin must be active. The attacker must have a valid login for a user with at least the
Contributorrole (common for sites with multiple authors).
3. Code Flow
- The plugin registers REST API routes during
rest_api_init. - The route
leadin/v1/configis handled by a callback that relies onLeadin\Admin\AdminConstants::get_admin_constants()(defined inpublic/admin/class-adminconstants.php). - Inside
class-adminconstants.php, the function (likelyget_admin_constantsorget_instance_data) aggregates environment metadata. - It calls the WordPress core function
get_plugins()to populate a list of installed software. - The REST route's
permission_callbacklikely only checks if the user is logged in (is_user_logged_in) or uses a low-level capability check likeedit_posts(available to Contributors), instead ofmanage_options(Administrators only). - The aggregated data is returned as a JSON response.
4. Nonce Acquisition Strategy
To interact with the WordPress REST API while authenticated, a wp_rest nonce is required in the X-WP-Nonce header.
- Identity Variable: The HubSpot plugin often localizes its own config, but the standard
wp_restnonce is always available in thewp-admindashboard. - Strategy:
- Log in as a Contributor.
- Navigate to any dashboard page (e.g.,
/wp-admin/index.php). - Extract the nonce from the
wpApiSettingsJavaScript object.
- Extraction Command:
// In browser console or browser_eval window.wpApiSettings.nonce
5. Exploitation Strategy
- Setup: Ensure the target WordPress site has the HubSpot plugin (v11.3.32) and several other plugins installed (to verify the leak).
- Create User: Create a user with the
Contributorrole. - Authentication: Authenticate the session using the Contributor credentials.
- Fetch Nonce: Use
browser_navigateto/wp-admin/andbrowser_evalto grabwindow.wpApiSettings.nonce. - Trigger Leak: Perform an HTTP GET request to the REST endpoint.
- URL:
http://<target>/wp-json/leadin/v1/config - Headers:
X-WP-Nonce: <extracted_nonce>Content-Type: application/json
- URL:
- Verify Data: Inspect the JSON response for a key containing plugin data (likely named
plugins,plugin_list, orinstalled_plugins).
6. Test Data Setup
- Plugin Version: Install
leadinversion11.3.32. - Contributor User:
- Username:
researcher - Password:
password123 - Role:
contributor
- Username:
- Noise Plugins: Install a few well-known plugins (e.g.,
akismet,contact-form-7,elementor) so the disclosure is obvious. - No Shortcode Needed: Unlike frontend vulnerabilities, this is an administrative REST API issue; simply being logged into
wp-adminis sufficient.
7. Expected Results
A successful exploit will return a 200 OK response with a JSON body. Example structure:
{
"wpVersion": "6.7.1",
"phpVersion": "8.1.0",
"installed_plugins": {
"akismet/akismet.php": {
"Name": "Akismet Anti-Spam",
"Version": "5.3",
...
},
"leadin/leadin.php": {
"Name": "HubSpot All-In-One Marketing",
"Version": "11.3.32",
...
}
},
...
}
8. Verification Steps
- Manual Check: Compare the JSON output with the output of
wp plugin list --format=jsonvia WP-CLI. - Code Audit: Verify the fix in 11.3.33 by checking the
permission_callbackin the REST route registration. It should now check formanage_options.
9. Alternative Approaches
If the REST endpoint /leadin/v1/config is not found, attempt to find where the "HubSpot Configuration" is loaded:
- Localized Data: Visit the HubSpot settings page in
wp-adminas a Contributor (if accessible). Usebrowser_eval("window.leadinConfig")orbrowser_eval("window.hubspotConfig"). Even if the page displays "Access Denied," the script might still be enqueued and localized. - AJAX: Check for an AJAX action named
leadin_get_configorleadin_constantsviaadmin-ajax.php. - Other Routes: Search for other routes registered under the
leadin/v1namespace using thewp-jsonindex:GET /wp-json/leadin/v1.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.