CVE-2026-39579

bBlocks – Essential Gutenberg Blocks & Patterns Collection <= 2.0.31 - Authenticated (Contributor+) Privilege Escalation

highIncorrect Privilege Assignment
8.8
CVSS Score
8.8
CVSS Score
high
Severity
2.0.32
Patched in
6d
Time to patch

Description

The bBlocks – Essential Gutenberg Blocks & Patterns Collection plugin for WordPress is vulnerable to privilege escalation in all versions up to, and including, 2.0.31. This makes it possible for authenticated attackers, with Contributor-level access and above, to elevate their privileges to that of an administrator.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=2.0.31
PublishedApril 16, 2026
Last updatedApril 21, 2026
Affected pluginb-blocks

What Changed in the Fix

Changes introduced in v2.0.32

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-39579 (bBlocks Privilege Escalation) ## 1. Vulnerability Summary The **bBlocks – Essential Gutenberg Blocks & Patterns Collection** plugin (<= 2.0.31) contains an authenticated privilege escalation vulnerability. The flaw exists because settings-saving functio…

Show full research plan

Exploitation Research Plan: CVE-2026-39579 (bBlocks Privilege Escalation)

1. Vulnerability Summary

The bBlocks – Essential Gutenberg Blocks & Patterns Collection plugin (<= 2.0.31) contains an authenticated privilege escalation vulnerability. The flaw exists because settings-saving functionality (likely via AJAX or REST API) uses an incorrect capability check (e.g., edit_posts instead of manage_options). This allows users with Contributor roles or higher to modify arbitrary WordPress options. By updating the default_role to administrator and enabling users_can_register, an attacker can create a new admin account or potentially modify their own user meta to gain full administrative access.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (most likely) or the WordPress REST API (/wp-json/).
  • Action/Route: Likely b_blocks_save_settings or a REST endpoint like /wp-json/b-blocks/v1/settings.
  • Payload Parameters:
    • action: The AJAX action string (e.g., b_blocks_save_settings).
    • _wpnonce / nonce: Security token.
    • settings: An array or JSON object containing option keys and values.
  • Vulnerable Parameters: Any parameter that maps directly to update_option().
  • Authentication: Authenticated as Contributor (requires wp-login.php session).

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX handler or REST route for the admin dashboard (referenced in build/admin-dashboard.js).
  2. Capability Check: The handler performs a check using current_user_can( 'edit_posts' ). Since Contributors can edit posts, they pass this check.
  3. Input Processing: The handler takes a list of settings from $_POST or the REST body.
  4. Sink: The handler iterates through the input and calls update_option( $key, $value ) without a whitelist, or with a whitelist that includes sensitive WordPress core options.

4. Nonce Acquisition Strategy

The admin dashboard logic is contained in build/admin-dashboard.js. The nonce is likely localized using wp_localize_script in a PHP file (e.g., includes/admin/class-admin.php or the main plugin file).

  1. Identify Shortcode/Page: Check the main plugin PHP for add_menu_page or add_shortcode. Gutenberg plugins often enqueue settings nonces on the block editor screen or a custom dashboard page.
  2. Contributor Access: Navigate to a page accessible by a Contributor (e.g., /wp-admin/post-new.php or the plugin's dashboard if allowed).
  3. Extraction:
    • The JS localization key is likely bBlocksAdminData or bBlocksSettings.
    • Use browser_eval to extract the nonce:
      // Example targets to check
      window.bBlocksAdminData?.nonce
      window.bBlocksSettings?.nonce
      window.bBlocksData?.nonce
      
  4. Action Check: Verify if the nonce action in wp_create_nonce matches the action in check_ajax_referer or wp_verify_nonce.

5. Exploitation Strategy

Step 1: Discover the Endpoint

Grep the plugin directory for the following:

  • grep -r "wp_ajax_b_blocks" .
  • grep -r "register_rest_route" .
  • grep -r "update_option" .

Step 2: Prepare Payload

The goal is to modify core WordPress settings.
Target Options:

  • default_role -> administrator
  • users_can_register -> 1

Sample AJAX Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=b_blocks_save_settings&nonce=[EXTRACTED_NONCE]&settings[default_role]=administrator&settings[users_can_register]=1

Step 3: Execute Registration

Once the options are changed, navigate to /wp-login.php?action=register to create a new account, which will now default to the Administrator role.

6. Test Data Setup

  1. Install WordPress with the b-blocks plugin (version <= 2.0.31).
  2. Create a user with the Contributor role.
  3. Verify current settings: wp option get default_role (should be subscriber) and wp option get users_can_register (should be 0).

7. Expected Results

  • The server returns a 200 OK or {"success":true}.
  • The default_role option in the database is updated to administrator.
  • The users_can_register option is updated to 1.

8. Verification Steps

  1. Check Options via CLI:
    wp option get default_role
    wp option get users_can_register
    
  2. Check User Escalation (Alternative): If the payload allowed targeting wp_capabilities for a specific user ID, check the role of the contributor:
    wp user get [CONTRIBUTOR_ID] --field=roles
    

9. Alternative Approaches

  • Direct Meta Update: If the vulnerable function uses update_user_meta instead of update_option, target the Contributor's user ID to change their wp_capabilities to a:1:{s:13:"administrator";b:1;}.
  • REST API Route: If the plugin uses REST, the request would be:
    POST /wp-json/b-blocks/v1/settings HTTP/1.1
    Content-Type: application/json
    X-WP-Nonce: [EXTRACTED_NONCE]
    
    {
      "default_role": "administrator",
      "users_can_register": 1
    }
    
    (Check register_rest_route calls to confirm the exact path and parameter structure.)
Research Findings
Static analysis — not yet PoC-verified

Summary

The bBlocks plugin (<= 2.0.31) incorrectly uses the 'edit_posts' capability for its settings-saving functionality rather than the 'manage_options' capability. This allows authenticated users with Contributor-level permissions or higher to modify arbitrary WordPress options, including sensitive core settings.

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.31/build/admin-dashboard.asset.php /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.32/build/admin-dashboard.asset.php
--- /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.31/build/admin-dashboard.asset.php	2026-03-03 09:27:24.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.32/build/admin-dashboard.asset.php	2026-03-03 09:27:24.000000000 +0000
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-i18n'), 'version' => '98328efe16bcd91feec8');
+<?php return array('dependencies' => array('react', 'react-dom', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-i18n'), 'version' => 'ef0b16b7bbdff4475bfc');
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.31/build/admin-dashboard.js /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.32/build/admin-dashboard.js
--- /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.31/build/admin-dashboard.js	2026-03-03 09:27:24.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/b-blocks/2.0.32/build/admin-dashboard.js	2026-03-03 09:27:24.000000000 +0000
... (truncated)

Exploit Outline

1. Authentication: Log in as a user with at least Contributor-level privileges. 2. Nonce Acquisition: Access the plugin dashboard or a post editing page to extract the security nonce from the localized JavaScript data (e.g., window.bBlocksAdminData.nonce). 3. Payload Preparation: Construct a POST request targeting the settings-saving endpoint (either wp-admin/admin-ajax.php with the action 'b_blocks_save_settings' or the plugin's REST API endpoint). 4. Privilege Escalation: Include parameters in the request to update sensitive WordPress options, such as setting 'default_role' to 'administrator' and 'users_can_register' to '1'. 5. Execution: Submit the request. Because the server improperly validates the user's capability as 'edit_posts', the request is authorized. 6. Verification: Navigate to the registration page to create a new administrator account or observe the elevation of the default role.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.