CVE-2026-2128

Breeze Cache <= 2.5.2 - Unauthenticated Exposure of Sensitive Information to an Unauthorized Actor via Crafted Login Cookie

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
2.5.3
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Low
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=2.5.2
PublishedMay 28, 2026
Last updatedMay 29, 2026
Affected pluginbreeze

What Changed in the Fix

Changes introduced in v2.5.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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: Cookie header containing a key starting with wordpress_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

  1. Request Initialization: A request is made to a WordPress URL.
  2. Early Loading: WordPress (or advanced-cache.php) includes inc/cache/execute-cache.php early in the boot process.
  3. Cookie Parsing: The code iterates through $_COOKIE to find a key matching wordpress_logged_in_.
  4. 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.
  5. 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).
  6. Information Disclosure: If the file exists, it is read and printed to the output buffer using readfile() or file_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 uses strpos($key, 'wordpress_logged_in_') === 0.
  • Cookie Value: admin|12345. The plugin splits at the first | and takes admin as 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

  1. Install Plugin: Install Breeze Cache version 2.5.2.
  2. Configure Plugin:
    • Use wp option update breeze_manager_options ... to enable caching.
    • Specifically, set breeze-cache-logged-in-user to 1.
  3. 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].
  4. Generate Cache:
    • Use the browser_navigate tool to log in as victim_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/.

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

  1. Check Cache Directory: Use ls -R wp-content/cache/breeze/ to confirm files are being created with user-specific identifiers in their names.
  2. Examine Response Content: Verify that the http_request response 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 for wordpress_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) vs admin|fake. (The source specifically mentions substr on the raw cookie value).
Research Findings
Static analysis — not yet PoC-verified

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

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.2/breeze.php /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.3/breeze.php
--- /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.2/breeze.php	2026-05-15 07:59:18.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.3/breeze.php	2026-05-21 11:01:36.000000000 +0000
@@ -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() );
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.2/changelog.txt /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.3/changelog.txt
--- /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.2/changelog.txt	2026-05-15 07:59:18.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.3/changelog.txt	2026-05-21 11:01:36.000000000 +0000
@@ -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.
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.2/readme.txt /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.3/readme.txt
--- /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.2/readme.txt	2026-05-15 07:59:18.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/breeze/2.5.3/readme.txt	2026-05-21 11:01:36.000000000 +0000
@@ -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.