Breeze Cache <= 2.5.2 - Unauthenticated Exposure of Sensitive Information to an Unauthorized Actor via Crafted Login Cookie
Description
The Breeze plugin for WordPress is vulnerable to Exposure of Sensitive Information to an Unauthorized Actor in all versions up to, and including, 2.5.2 This is due to improper verification of the `wordpress_logged_in_` cookie in the `inc/cache/execute-cache.php` file when the "Cache Logged-in Users" setting is enabled. The plugin parses the username directly from the cookie value (e.g., `username|hash`) using `substr()` to retrieve the corresponding cache file but fails to verify the session's cryptographic signature or validity with WordPress core. This makes it possible for unauthenticated attackers to supply a crafted cookie (e.g., `wordpress_logged_in_fake=admin|fake`) to trick the plugin into serving the cached HTML content generated for an administrator, leading to the disclosure of sensitive information such as private posts (including their full content), the Admin Bar, WordPress nonces, and other data visible only to logged-in administrators or other users.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
What Changed in the Fix
Changes introduced in v2.5.3
Source Code
WordPress.org SVN# Research Plan: CVE-2026-2128 - Breeze Cache Sensitive Information Exposure ## 1. Vulnerability Summary The Breeze Cache plugin (versions <= 2.5.2) contains a flaw in its early-loading cache execution logic. When the "Cache Logged-in Users" feature is enabled, the plugin attempts to serve user-spe…
Show full research plan
Research Plan: CVE-2026-2128 - Breeze Cache Sensitive Information Exposure
1. Vulnerability Summary
The Breeze Cache plugin (versions <= 2.5.2) contains a flaw in its early-loading cache execution logic. When the "Cache Logged-in Users" feature is enabled, the plugin attempts to serve user-specific cached HTML files by identifying the user from the wordpress_logged_in_ cookie.
The vulnerability exists in inc/cache/execute-cache.php because the plugin parses the username directly from the cookie string using substr() and strpos() without validating the cryptographic HMAC signature attached to the WordPress cookie. An unauthenticated attacker can provide a malformed or crafted cookie that specifies a high-privilege username (e.g., admin), prompting the plugin to serve the cached version of a page intended only for that administrator. This exposes private posts, admin bars, nonces, and other sensitive session-specific data.
2. Attack Vector Analysis
- Vulnerable File:
inc/cache/execute-cache.php - Trigger Setting: The "Cache Logged-in Users" option must be enabled (
breeze-cache-logged-in-user). - HTTP Parameter:
Cookieheader containing a key starting withwordpress_logged_in_. - Payload Structure:
wordpress_logged_in_[hash]=[username]|[anything] - Authentication: Unauthenticated.
- Precondition: A cached version of the target page for the target user must already exist in the
wp-content/cache/breeze/directory.
3. Code Flow
- Request Initialization: A request is made to a WordPress URL.
- Early Loading: WordPress (or
advanced-cache.php) includesinc/cache/execute-cache.phpearly in the boot process. - Cookie Parsing: The code iterates through
$_COOKIEto find a key matchingwordpress_logged_in_. - Insecure Extraction:
- It identifies the cookie value.
- It finds the first pipe
|character. - It extracts everything before the pipe as the
$username. - Crucially: It does not call
wp_validate_auth_cookie()or any signature verification because the full WordPress environment isn't always loaded at this stage of caching.
- Cache Lookup:
- The plugin generates a cache key based on the URL and the extracted
$username. - It constructs a file path:
wp-content/cache/breeze/[url_hash]/breeze_[user_hash].html(or similar).
- The plugin generates a cache key based on the URL and the extracted
- Information Disclosure: If the file exists, it is read and printed to the output buffer using
readfile()orfile_get_contents(), then execution terminates (exit).
4. Nonce Acquisition Strategy
No nonce is required for this exploit.
The vulnerability occurs during the cache-serving phase, which happens before WordPress processes nonces. In fact, one of the primary impacts of this vulnerability is the leakage of valid administrative nonces found within the served cached HTML, which could then be used for further attacks.
5. Exploitation Strategy
Step 1: Discover the Admin Username
Identify a valid administrator username (usually admin or can be found via author archives).
Step 2: Prepare the Target
Wait for (or trigger) the administrator to visit a sensitive page (like a private post or the homepage) while "Cache Logged-in Users" is active. This populates the cache.
Step 3: Craft the Request
Send an unauthenticated request to the target URL with a spoofed login cookie.
HTTP Request:
GET /?p=[private_post_id] HTTP/1.1
Host: localhost
Cookie: wordpress_logged_in_bypass=[admin_username]|invalid_hash_ignored_by_plugin
Payload Details:
- Cookie Name: Must start with
wordpress_logged_in_. The suffix doesn't matter as the plugin typically usesstrpos($key, 'wordpress_logged_in_') === 0. - Cookie Value:
admin|12345. The plugin splits at the first|and takesadminas the identity.
Step 4: Analyze Response
If successful, the response will contain the HTML rendered for the admin, including:
- Content of private/draft posts.
- The WordPress Admin Bar (at the top of the HTML).
- Administrative nonces (e.g.,
_wpnonce).
6. Test Data Setup
- Install Plugin: Install Breeze Cache version 2.5.2.
- Configure Plugin:
- Use
wp option update breeze_manager_options ...to enable caching. - Specifically, set
breeze-cache-logged-in-userto1.
- Use
- Create Content:
- Create an admin user:
wp user create victim_admin admin@example.com --role=administrator --user_pass=password123. - Create a private post:
wp post create --post_title='Secret Admin Intel' --post_content='Flag: EXFIL_SUCCESS' --post_status=private --post_author=[admin_id].
- Create an admin user:
- Generate Cache:
- Use the
browser_navigatetool to log in asvictim_admin. - Navigate to the private post URL to ensure Breeze generates a cache file for this user.
- Verify the cache file exists in
wp-content/cache/breeze/.
- Use the
7. Expected Results
- The HTTP response from the unauthenticated request (with the crafted cookie) should return
200 OK. - The body of the response should contain the string
Flag: EXFIL_SUCCESS. - The body should contain the class
admin-bar, indicating the server "thinks" it's serving a logged-in administrator.
8. Verification Steps
- Check Cache Directory: Use
ls -R wp-content/cache/breeze/to confirm files are being created with user-specific identifiers in their names. - Examine Response Content: Verify that the
http_requestresponse for the private post does NOT return a 404 or a login redirect, but instead returns the full content of the private post.
9. Alternative Approaches
If the standard wordpress_logged_in_ cookie name is not being picked up:
- Check if the site uses a custom
COOKIEHASH. The plugin may look forwordpress_logged_in_followed by a specific MD5 hash. This hash can be calculated from the site URL. - Try requesting the homepage (
/). Often the homepage is cached for admins and contains "Edit Post" links and nonces that prove the bypass. - If the username extraction uses a different delimiter in newer PHP versions or specific OS environments, test
admin%7Cfake(URL encoded) vsadmin|fake. (The source specifically mentionssubstron the raw cookie value).
Summary
The Breeze Cache plugin (versions <= 2.5.2) is vulnerable to sensitive information disclosure when the "Cache Logged-in Users" feature is active. The plugin extracts usernames from the 'wordpress_logged_in_' cookie without verifying its cryptographic HMAC signature, allowing unauthenticated attackers to view cached pages generated for other users, such as administrators, by providing a crafted cookie.
Security Fix
@@ -2,7 +2,7 @@ /** * Plugin Name: Breeze * Description: Breeze is a cache plugin with extensive options to speed up your website. All the options including Varnish Cache are compatible with Cloudways hosting. - * Version: 2.5.2 + * Version: 2.5.3 * Text Domain: breeze * Domain Path: /languages * Author: Cloudways @@ -37,7 +37,7 @@ define( 'BREEZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); } if ( ! defined( 'BREEZE_VERSION' ) ) { - define( 'BREEZE_VERSION', '2.5.2' ); + define( 'BREEZE_VERSION', '2.5.3' ); } if ( ! defined( 'BREEZE_SITEURL' ) ) { define( 'BREEZE_SITEURL', get_site_url() ); @@ -1,5 +1,9 @@ == Changelog == += 2.5.3 = + +* Compatibility: Verified compatibility with WordPress 7.0. + = 2.5.2 = * Improved: Refined multisite handling across settings, cache management, import/export, and reset actions for more consistent behavior and better scope control. @@ -2,9 +2,9 @@ Contributors: Cloudways Tags: cache,caching, performance, wp-cache, cdn Requires at least: 6.0 -Tested up to: 6.9 +Tested up to: 7.0 Requires PHP: 7.4 -Stable tag: 2.5.2 +Stable tag: 2.5.3 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -160,6 +160,10 @@ == Changelog == += 2.5.3 = + +* Compatibility: Verified compatibility with WordPress 7.0. + = 2.5.2 = * Improved: Refined multisite handling across settings, cache management, import/export, and reset actions for more consistent behavior and better scope control.
Exploit Outline
1. Target Site Setup: Ensure the 'Cache Logged-in Users' setting is enabled in the Breeze Cache plugin and identify a target username (e.g., 'admin'). 2. Populate Cache: Confirm that a cached file for the target user exists for the URL you intend to request. This typically happens when the user visits the page while logged in. 3. Craft Payload: Create a HTTP GET request to the target URL. 4. Inject Spoofed Cookie: Add a 'Cookie' header containing a key starting with 'wordpress_logged_in_'. The value must be formatted as '[target_username]|', followed by any character (e.g., 'wordpress_logged_in_spoof=admin|anything'). 5. Execution: Send the request unauthenticated. The plugin's early-loading cache logic will parse the username from the crafted cookie without validating the signature and serve the cached HTML file associated with that user. 6. Exfiltration: Analyze the response for sensitive content such as private post data, the WordPress Admin Bar, and administrative nonces.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.