每个 Java 软件架构师都应该知道的 20 件事
.NET 损坏认证指南:示例和预防
在本文中,我们将解决断开的身份验证问题,探讨身份验证的复杂性,并向您展示如何为您的网站提供适当的安全机制。
首先,我将简要讨论什么是身份验证失效。然后,我将使用示例来说明身份验证失效攻击是什么样子,以及它们针对哪些漏洞。最后,我将提供一些缓解策略来解决这些漏洞。
但在开始之前,我想澄清一下,本文是为 .NET 开发人员撰写的。说完这些,我们就开始吧。
什么是失效身份验证?
“破坏身份验证”是一个总称,描述了攻击者可以利用来劫持您的系统并冒充用户的几个漏洞。
身份验证机制可确保只有经过验证的用户才能访问 Web 应用程序上的信息和权限。但是,当攻击者成功绕过该过程并冒充用户时,该机制就会“失效”。本质上,攻击者会跳过登录安全并获取被黑客入侵用户的权限。
这些漏洞与糟糕的会话管理和凭证管理密不可分。攻击者可以通过劫持会话 ID 或窃取登录凭证来伪装成用户。这种漏洞使攻击者能够窃取密码、密钥或会话令牌、用户帐户信息和其他详细信息,以冒充用户身份。
身份验证失败是如何发生的
让我们看看攻击者究竟如何劫持您的系统。
凭证管理不善导致身份验证失败
由于凭证管理实施不力,攻击者可以劫持您的身份验证机制来访问系统。
不良的凭证管理允许攻击者通过多种方式实现此目的。一种是允许使用“12345”或“password”等弱密码。当您的系统允许用户创建弱密码时,攻击者可以使用暴力破解、彩虹表和字典等密码破解技术。
另一种可能让攻击者破坏您安全的方法就是使用弱加密技术。当您的系统使用不充分的加密机制(如 base64)和哈希算法(如 SHA1 或 MD5)时,您的用户凭据将在入侵期间暴露。
会话管理不善导致身份验证失败
每当用户与您的网站互动时,您的应用程序都会发出会话 ID 并记录他们的互动。正如OWASP 破解身份验证建议所述,此会话 ID 相当于您的原始登录凭据。因此,如果攻击者窃取了您的会话 ID,他基本上可以冒充您的身份。
这种违规行为称为会话劫持。
身份验证失败的示例
以下是一些破坏身份验证攻击的详细示例。
密码喷洒
“密码喷洒”是指攻击者试图入侵安全账户,使用简单且弱的密码,例如“12345”或“password”。
凭证填充
每当具有大量用户的系统因凭证加密不当而发生漏洞时,用户就很容易受到凭证填充的攻击。
凭证填充是指使用从其他违规行为中获取的凭证。这种方法假设大量用户可能会在不同平台上使用被盗凭证。
会话劫持
使用会话 ID 会使用户容易受到劫持和冒充。例如,假设用户忘记注销。在这种情况下,任何其他人都可以劫持他们的会话并在您的系统上充当受害者。此外,如果在身份验证之前和之后发出相同的 ID,则可能会为一种称为会话固定的攻击打开大门。
会话 ID URL
如果您的系统通过将会话 ID 附加到 URL 来实现会话 ID,那么任何能够访问该 URL 的人都可以冒充用户的身份。攻击者可以通过劫持不安全的 Wi-Fi 连接、中间人攻击或简单地窃听地址栏来实现这一点。
网络钓鱼攻击
最后,用户可能容易受到钓鱼攻击,这些攻击会发送看似合法的网站链接,诱使他们交出登录凭据。最后这种攻击非常臭名昭著,而且很难应对,因为它完全依赖于用户发现它们的能力。
解决身份验证漏洞
为了解决上述漏洞,您需要遵循开放 Web 应用程序安全项目 (OWASP) 的最佳实践。幸运的是,您可以使用项目中的配置文件在 ASP.NET Core 中激活大多数这些建议。
安全密码存储
您必须对所有密码进行加密、哈希处理和加盐处理。这可以在发生泄露时保护用户,并减缓暴力攻击和其他恶意攻击。值得庆幸的是,如果您使用的是 ASP.NET Core Identity 框架,那么您已经实现了安全的密码哈希和独特的加盐机制。ASP.NET Core Identity 使用 PBKDF2 哈希函数来处理密码,并为每个用户生成随机盐。
不允许使用弱密码
您必须要求所有用户在指定密码时满足特定要求。例如,将密码设置为特定长度并要求包含特殊字符和字母以及数字有助于防止凭据被盗。因此,您的系统将拒绝不符合要求的密码。
您可以通过修改 IdentityOptions 方法来做到这一点,如下所示:
services.Configure<IdentityOptions>(options => {
// Password settings
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.Password.RequiredUniqueChars = 6;
});
请记住,其中一些规范比其他规范能更好地保护用户,但如果用户不遵守这些规范,它们也可能产生相反的效果。
添加严格的凭证恢复流程
我建议你实施严格的凭证恢复流程。这应该包括几项验证检查和步骤,使攻击者难以滥用凭证并付出高昂代价。
您可以通过在前面的代码中添加以下几行来实现这一点:
services.Configure<IdentityOptions>(options => {
// Password settings
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.Password.RequiredUniqueChars = 6;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts = 10;
options.SignIn.RequireConfirmedEmail = true;
options.User.RequireUniqueEmail = true;
});
实施密码保护措施
密码保护机制被破解后,密码被泄露的用户的账户将被锁定。此外,您可以配置此机制,在用户更改密码时恢复访问权限。这样,您就可以确保用户有机会在攻击者窃取密码时防止损失。
您可以使用名为 PwnedPassword 的 Git 项目实现此功能,该项目将提供已泄露密码的更新存储库,以便实时进行交叉验证。
调节会话长度
所有 Web 应用程序都必须在一定时间不活动后结束用户会话。此时间长度取决于应用程序的类型。例如,流媒体平台可能需要长时间不活动,而敏感的银行网站则应有较短的时间限制。
要调节会话的长度,请将以下行添加到项目配置文件中。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
/// ADD THIS
builder.Services.AddDistributedMemoryCache();
/// ADD THIS
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
/// ADD THIS
app.UseSession();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
改善会话管理
您的平台必须在每次身份验证成功后提供单独的会话 ID。此外,您的系统必须在会话结束后立即使旧会话 ID 失效,以防止劫持。
不要使用会话 ID URL
在所有情况下,您都必须使用 SSL 保护 Web URL,但不包含会话 ID。
多因素身份验证
多因素身份验证 (MFA) 是您可以使用的最强大的保护机制之一。MFA 需要额外的凭证来验证用户的身份。例如,通过邮寄或短信向用户发送一次性密码 (OTP)。
网络钓鱼
定期向用户宣传网络钓鱼攻击和弱密码的潜在风险至关重要。每月或每季度发送电子邮件提醒用户保持警惕和谨慎通常就足够了。
文章来源:.NET Broken Authentication Guide: Examples and Prevention