ASP.NET Core XSRF/CSRF攻击

2023-12-13 11:15:05 浏览数 (2)

跨站请求伪造(CSRF)是针对Web应用攻击常用的一种手段,恶意的Web应用可以影响客户端浏览器与信任该浏览器的Web 应用之间的交互,因为 Web 浏览器会在向网站发送每个请求时自动发送某些类型的身份验证令牌。这种利用形式也被称为one-click attack或者session riding,因为攻击利用了用户之前经过身份验证的会话。跨站请求伪造也被称为 XSRF 或 CSRF

我们可以理解为攻击者利用你的名义向Web应用程序发送请求来完成它想要达到的目的

1 XSRF/CSRF 攻击的一个例子:

(1) 用户登录 www.good-banking-site.example.com,服务器给该用户颁发了身份验证 cookie,该站点容易受到攻击,因为它信任任何带有有效身份验证 cookie 的请求

(2) 用户无意浏览恶意站点 www.bad-crook-site.example.com

(3) 恶意站点 www.bad-crook-site.example.com 包含如下HTML 表单:

代码语言:javascript复制
<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>

注意,表单的提交是向受信任的站点提交,而不是向恶意站点提交,这是 XSRF/CSRF中所描述的 "跨站"

(4) 用户选择提交按钮,浏览器发起请求并自动包含请求域的身份验证cookie,即 www.good-banking-site.example.com

(5) 该请求在 www.good-banking-site.example.com 服务器上运行,使用用户的身份,可以使用经过身份验证用户进行任何事情的操作

2 阻止XSRF/CSRF

Asp.Net Core 中使用Antiforgery中间件来防御XSRF/CSRF攻击,当我们在启动项中调用如下API时会自动将该中间件添加到应用程序

  • AddControllersWithViews
  • MapRazorPages
  • MapControllerRoute
  • MapBlazorHub

<form asp-antiforgery="true">或@Html.AntiForgeryToken()会生成防伪token,默认的FormTagHelper表单是开启,Razor文件中的下面标签那会自动生成防伪token:

代码语言:javascript复制
<form method="post">
    <!-- ... -->
</form>

生成的HTML如下:

我们也可以通过使用下面三种方式移除防伪token

(1) 显示调用表单的asp-antiforgery属性来禁用

代码语言:javascript复制
<form method="post" asp-antiforgery="false">
    <!-- ... -->
</form>

(2) 不使用FormTagHelper表单

代码语言:javascript复制
<!form method="post">
    <!-- ... -->
</!form>

(3) 移除FormTagHelper标签

代码语言:javascript复制
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers

防范 CSRF 攻击最常见的方法是使用同步令牌模式(Synchronizer Token Pattern,STP),STP 在用户请求携带表单数据的页面时被使用:

(1) 服务器将与当前用户身份关联的令牌发送给客户端

(2) 客户端将令牌发送回服务器进行验证

(3) 如果服务器收到的令牌与已经认证的用户身份不匹配,请求将被拒绝

生成的token是唯一并且不可预测的,token还可以用于确保请求的正确顺序(例如,确保请求顺序为:页面 1 > 页面 2 > 页面 3)

3 配置防伪特性

我们可以使用如下代码配置访问标签名称:

代码语言:javascript复制
builder.Services.AddAntiforgery(options =>
{
    //防伪造系统用于在视图中呈现防伪造令牌的隐藏表单域的名称
    options.FormFieldName = "AntiforgeryFieldname";
    //防伪造系统使用的标头的名称。如果为 null,则系统仅考虑表单数据
    options.HeaderName = "X-XSRF-TOKEN";
    options.SuppressXFrameOptionsHeader = false;
});

4 验证Token

我们可以使用ValidateAntiForgeryToken特性来验证防伪token

代码语言:javascript复制
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
    // ...

    return RedirectToAction();
}

也可以使用AutoValidateAntiforgeryToken,该特性不会验证下列请求 GET,HEAD,OPTIONS,TRACE,它可以在应用程序中作为全局过滤器来触发防伪token验证,该特性可以应用于如下请求POST,PUT,PATCH,DELETE不需要将ValidateAntiForgeryToken特性提交到每个action上

代码语言:javascript复制
//全局示例 
//可以使用 IgnoreAntiforgeryToken 筛选器,给指定的Action(或控制器)无需防伪造令牌
builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});

你也可以使用IgnoreAntiforgeryToken特性来忽视防伪token的验证

源代码地址:

https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.Security/AspNetCore.XSRF

0 人点赞