Web 浏览器会随着对网站的每个请求自动发送cookie。例如在A网页中对B网页发送请求,浏览器就会自动带上B网页的cookie,如果B网页采用基于cookie的身份验证,A网页就能冒充用户给B网页发送请求。这种形式的攻击就是跨网站请求伪造(Cross-site request forgery, CSRF),也称为XSRF。
CSRF 攻击并不局限于利用 Cookie,基本身份验证和摘要式身份验证也容易受到攻击。 用户使用基本或摘要式身份验证登录后,浏览器会自动发送凭据,直到会话结束。
CSRF 攻击示例:
- 用户使用表单身份验证登录到 www.good-banking-site.example.com。 服务器对用户进行身份验证,并发出包含身份验证 cookie 的响应。如果此网站信任收到的任何带有有效身份验证cookie的请求,那么就会容易受到CSRF攻击。
- 用户访问恶意网站 www.bad-crook-site.example.com。
恶意网站 www.bad-crook-site.example.com 包含类似于以下示例的 HTML 表单:- <h1>Congratulations! You're a Winner!</h1>
- <form action="https://www.good-banking-site.example.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 将发送到www.good-banking-site.example.com网站。
- 用户点击提交按钮,浏览器发出请求,并自动包括所请求域www.good-banking-site.example.com 的身份验证cookie 。因此请求可以执行经过身份验证的用户可执行的任何操作。
除了用户点击按钮来提交表单外,恶意网站还可以通过以下方式执行攻击:
- 运行自动提交表单的脚本。
- 以 AJAX 请求形式发送表单提交。
- 使用 CSS 隐藏表单。
防范跨网站请求伪造攻击
防范CSRF攻击最常用的方法是采用同步令牌模式(STP):
- 服务器为每个用户会话生成一个随机且唯一的令牌发送到客户端。因为同源策略,其他网页不能读取到此令牌。
- 发送请求时,客户端将令牌包含在请求头中发送回服务器进行验证。而恶意网站伪造此请求时,浏览器不会自动附加请求头。
- 如果服务器收到的令牌与已认证用户的身份不符,那么该请求将被拒绝。
例如,ASP.NET Core MVC或Razor Pages会在页面中添加隐藏的表单域,其包含了防伪令牌:- [/code]发送表单请求时,将防伪令牌添加到表单字段或添加到RequestVerificationToken请求头发送给服务器。当请求标头和表单有效负载中都提供了防伪造令牌时,仅验证标头中的令牌。
- 另一种方式是服务器将防伪令牌添加到cookie中,客户端从cookie中读取防伪令牌添加到请求头发送请求。
-
- [size=5]ASP.NET Core 中的防伪造[/size]
- 在Program.cs中调用以下 API 之一时,防伪造中间件将自动添加到容器:
- [list]
- [*]AddMvc
- [*]MapRazorPages
- [*]MapControllerRoute
- [*]AddRazorComponents
- [/list]
- [size=4]最小API添加防伪造中间件[/size]
- [code]var builder = WebApplication.CreateBuilder();
- builder.Services.AddAntiforgery();
- var app = builder.Build();
- app.UseAntiforgery();
- app.MapGet("/", () => "Hello World!");
- app.Run();
复制代码 调用 AddAntiforgery 和 UseAntiforgery(IApplicationBuilder) 在 DI 中注册防伪造服务。
手动启用时,防伪造中间件必须在身份验证和授权中间件之后运行,以防止在用户未经身份验证时读取表单数据。
配置防伪造
在Program.cs中配置AntiforgeryOptions:- builder.Services.AddAntiforgery(options =>
- {
- options.FormFieldName = "__RequestVerificationToken";
- options.HeaderName = "RequestVerificationToken";
- options.Cookie.Name = "XSRF-TOKEN";
- });
复制代码 选项说明Cookie确定用于创建防伪造 Cookie 的设置。FormFieldName防伪造系统用于在视图中呈现防伪造令牌的隐藏表单域的名称。HeaderName防伪造系统使用的标头的名称。 如果为 null,则系统仅考虑表单数据。SuppressXFrameOptionsHeader指定是否禁止生成 X-Frame-Options 标头。 默认情况下,标头是使用值“SAMEORIGIN”生成的。 默认为 false。
生成防伪造令牌
IAntiforgery 提供用于配置防伪功能的 API,可通过依赖注入获取IAntiforgery。
示例:生成防伪令牌,并作为cookie在响应中发送:- app.UseRouting();
- app.UseAuthorization();
- var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
- app.Use((context, next) =>
- {
- var requestPath = context.Request.Path.Value;
- if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
- || string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
- {
- var tokenSet = antiforgery.GetAndStoreTokens(context);
- context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
- new CookieOptions { HttpOnly = false });
- }
- return next(context);
- });
复制代码 前面的示例设置了一个名为 XSRF-TOKEN 的 Cookie。客户端可以读取此 Cookie,并将其值作为附加到 AJAX 请求的标头提供。
例如,Angular 包含内置的 XSRF 保护 ,默认情况下会读取名为 XSRF-TOKEN 的 Cookie。
要求防伪验证
ASP.NET Core 包含三个用于处理防伪造令牌的筛选器:
- ValidateAntiForgeryToken
- AutoValidateAntiforgeryToken
- IgnoreAntiforgeryToken
ValidateAntiForgeryToken
ValidateAntiForgeryToken筛选器要求请求包含有效的防伪令牌,此筛选器可应用于Action、Controller或全局。- [HttpPost]
- [ValidateAntiForgeryToken]
- public IActionResult Index()
- {
- // ...
- return RedirectToAction();
- }
复制代码 AutoValidateAntiForgeryToken
AutoValidateAntiforgeryToken筛选器仅要求不安全的HTTP方法请求包含有效的防伪令牌,以下HTTP方法发出的请求不需要令牌:
示例:- [AutoValidateAntiforgeryToken]
- public class HomeController : Controller
复制代码 全局设置此筛选器:- builder.Services.AddControllersWithViews(options =>
- {
- options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
- });
复制代码 IgnoreAntiforgeryToken
如果 ValidateAntiForgeryToken 特性应用于控制器,则可以在Action用 IgnoreAntiforgeryToken 特性覆盖它。
IgnoreAntiforgeryToken筛选器用于消除指定Action或Controller对防伪令牌的要求。此筛选器将覆盖在更高级别指定的 ValidateAntiForgeryToken 和 AutoValidateAntiforgeryToken筛选器。
示例:- [IgnoreAntiforgeryToken]
- public IActionResult IndexOverride()
- {
- // ...
- return RedirectToAction();
- }
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |