ASP.NET Core 知识速递 - Day 8:每天进步一点

文摘   2024-10-21 08:21   日本  
这节我们讲解一下反伪造令牌,它是ASP.NET Core中的一项安全技术,用于防止跨站伪造请求(CSRF)攻击。在展开这个话题之前我们首先介绍一下什么是CSRF。
跨站请求伪造(CSRF)是一种针对托管在 Web 上的应用程序的攻击,恶意应用程序(通常指Web)可以影响客户端浏览器与信任该浏览器的Web 应用之间的交互。之所以有这种攻击,是因为 Web 浏览器会自动将用户身份验证令牌与每次发送给网站的请求一起打包发送。由于这种攻击利用了用户已认证的会话,它也被称为“一键攻击”或“会话骑乘”。跨站请求伪造也被称为 XSRF 或 CSRF。
例子:

1. 用户登录www.good-banking-site.example.com网站,服务器对用户进行身份验证并返回包含身份验证 Cookie 的响应。该站点容易受到攻击,因为它信任任何带有有效身份验证 Cookie 的请求。

2. 用户无访问了恶意站点:www.bad-crook-site.example.com.恶意站点包含了如下代码:

<h1>Congratulations! You're a Winner!</h1><form action="https://good-banking-site.com/api/account" method="post">    <input type="hidden" name="Transaction" value="withdraw" />    <input type="hidden" name="Amount" value="1000000" />    <input type="submit" value="Click to collect your prize!" /></form>

注意这个恶意站点的action是指向安全站点的地址,用户点击Submit提交按钮。

3. 用户点击提交时,浏览器包含自动包含认证的cookie请求正常站点
4. 该请求在 www.good-banking-site.example.com 服务器上运行,使用用户的身份验证上下文,并可以执行任何经过身份验证的用户被允许执行的操作。

CSRF 攻击之所以可能发生在使用 Cookie 进行身份验证的 Web 应用中,是因为:

1. 浏览器存储由 Web 应用程序生成的Cookie。
2. 存储的Cookie 包括经过身份验证用户的会话 Cookie。
3. 浏览器在每次请求中都会将与域相关的所有 Cookie 发送到 Web 应用程序,无论该请求是在浏览器内如何生成的,这应该是浏览器的锅。
为了防止CSRF攻击,服务器会生成一个反伪造Token。这正是APS.NET Core AntiForgery的实现原理。
using Microsoft.AspNetCore.Antiforgery;
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery(options =>{ options.Cookie.Name = "AntiForgery"; options.Cookie.Domain = "localhost"; options.Cookie.Path = "/"; options.FormFieldName = "Antiforgery"; options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;});
var app = builder.Build();
//These are the four default services available at Configureapp.Run(async context =>{ var antiForgery = context.RequestServices.GetService<IAntiforgery>(); if (HttpMethods.IsPost(context.Request.Method)) { await antiForgery.ValidateRequestAsync(context); await context.Response.WriteAsync("Response validated with anti forgery"); return; }
var token = antiForgery.GetAndStoreTokens(context);
context.Response.Headers.Append("Content-Type", "text/html"); await context.Response.WriteAsync($@" <html> <body> View source to see the generated anti forgery token <form method=""post""> <input type=""hidden"" name=""{token.FormFieldName}"" value=""{token.RequestToken}"" /> <input type=""submit"" value=""Push""/> </form> </body> </html> ");});
app.Run();

上面代码中:

1. 当用户加载包含表单的页面时,服务器会生成一个随机的反伪造令牌(AntiForgery Token)。这个令牌是唯一的,通常是通过加密算法生成,并与用户的会话相关联,反伪造令牌会被包含在生成的 HTML 中,作为一个隐藏字段。
2. 每当用户提交表单时,该令牌会随着表单数据一起发送到服务器。当用户提交表单时,ASP.NET Core 会自动验证提交的数据中是否包含有效的反伪造令牌。

[ValidateAntiForgeryToken] 特性,除了使用上面方法之外,还可以使用该特性在Action上进行验证。

源代码地址:
https://github.com/bingbing-gui/AspNetCore-Skill/tree/master/src/aspnetcore-knowledge-point/anti-forgery

桂迹
分享原创,记录痕迹!
 最新文章