Overview
In 2018, CVE-2018-8171 described a Security Feature Bypass in ASP.NET where the number of incorrect login attempts was not validated, which could allow attackers to bypass account protections during credential-stuffing or brute-force attempts. The exposure affected ASP.NET itself, as well as ASP.NET Core 1.0, 1.1, 2.0 and ASP.NET MVC 5.2, making it possible to bypass authentication checks under certain configurations.
The vulnerability stems from inconsistent tracking of failed logins across sign-in paths. If a developer disables lockout or uses lockoutOnFailure = false, the framework may not enforce throttling or account lockout for subsequent attempts, enabling continued guessing without the intended delay or restriction.
In real-world exploits, attackers could leverage multiple login attempts or mixed login methods to enumerate valid accounts and bypass basic protections. Patches exist and Microsoft recommends upgrading to patched releases and ensuring lockout mechanisms are consistently and correctly configured across all authentication flows.
Remediation involves enabling and properly configuring account lockouts, using PasswordSignInAsync with lockoutOnFailure = true, updating to patched framework versions, and adding MFA or rate limiting to reduce risk.
Affected Versions
ASP.NET Core 1.0, 1.1, 2.0; ASP.NET MVC 5.2
Code Fix Example
ASP.NET Core API Security Remediation
Vulnerable:
var result = await _signInManager.PasswordSignInAsync(userName, password, isPersistent: false, lockoutOnFailure: false);
Fixed:
var result = await _signInManager.PasswordSignInAsync(userName, password, isPersistent: false, lockoutOnFailure: true);
// Identity/config in Startup.cs (vulnerable):
sservices.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Identity/config in Startup.cs (fixed):
services.AddIdentity<ApplicationUser, IdentityRole>(options => {
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();