找回密码
 立即注册
首页 业界区 安全 防范跨网站请求伪造 (XSRF/CSRF) 攻击

防范跨网站请求伪造 (XSRF/CSRF) 攻击

旁拮猾 2025-8-14 08:32:31
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 表单:
    1. <h1>Congratulations! You're a Winner!</h1>
    2. <form action="https://www.good-banking-site.example.com/api/account" method="post">
    3.     <input type="hidden" name="Transaction" value="withdraw" />
    4.     <input type="hidden" name="Amount" value="1000000" />
    5.     <input type="submit" value="Click to collect your prize!" />
    6. </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会在页面中添加隐藏的表单域,其包含了防伪令牌:
  1. [/code]发送表单请求时,将防伪令牌添加到表单字段或添加到RequestVerificationToken请求头发送给服务器。当请求标头和表单有效负载中都提供了防伪造令牌时,仅验证标头中的令牌。
  2. 另一种方式是服务器将防伪令牌添加到cookie中,客户端从cookie中读取防伪令牌添加到请求头发送请求。
  3. [size=5]ASP.NET Core 中的防伪造[/size]
  4. 在Program.cs中调用以下 API 之一时,防伪造中间件将自动添加到容器:
  5. [list]
  6. [*]AddMvc
  7. [*]MapRazorPages
  8. [*]MapControllerRoute
  9. [*]AddRazorComponents
  10. [/list]‍
  11. [size=4]最小API添加防伪造中间件[/size]
  12. [code]var builder = WebApplication.CreateBuilder();
  13. builder.Services.AddAntiforgery();
  14. var app = builder.Build();
  15. app.UseAntiforgery();
  16. app.MapGet("/", () => "Hello World!");
  17. app.Run();
复制代码
调用 AddAntiforgery 和 UseAntiforgery(IApplicationBuilder) 在 DI 中注册防伪造服务。
手动启用时,防伪造中间件必须在身份验证和授权中间件之后运行,以防止在用户未经身份验证时读取表单数据。

配置防伪造

在Program.cs中配置AntiforgeryOptions:
  1. builder.Services.AddAntiforgery(options =>
  2. {
  3.     options.FormFieldName = "__RequestVerificationToken";
  4.     options.HeaderName = "RequestVerificationToken";
  5.     options.Cookie.Name = "XSRF-TOKEN";
  6. });
复制代码
选项说明Cookie确定用于创建防伪造 Cookie 的设置。FormFieldName防伪造系统用于在视图中呈现防伪造令牌的隐藏表单域的名称。HeaderName防伪造系统使用的标头的名称。 如果为 null,则系统仅考虑表单数据。SuppressXFrameOptionsHeader指定是否禁止生成 X-Frame-Options 标头。 默认情况下,标头是使用值“SAMEORIGIN”生成的。 默认为 false。‍
生成防伪造令牌

​IAntiforgery 提供用于配置防伪功能的 API,可通过依赖注入获取IAntiforgery。
示例:生成防伪令牌,并作为cookie在响应中发送:
  1. app.UseRouting();
  2. app.UseAuthorization();
  3. var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
  4. app.Use((context, next) =>
  5. {
  6.     var requestPath = context.Request.Path.Value;
  7.     if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
  8.         || string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
  9.     {
  10.         var tokenSet = antiforgery.GetAndStoreTokens(context);
  11.         context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
  12.             new CookieOptions { HttpOnly = false });
  13.     }
  14.     return next(context);
  15. });
复制代码
前面的示例设置了一个名为 XSRF-TOKEN 的 Cookie。客户端可以读取此 Cookie,并将其值作为附加到 AJAX 请求的标头提供。
例如,Angular 包含内置的 XSRF 保护 ,默认情况下会读取名为 XSRF-TOKEN 的 Cookie。

要求防伪验证

ASP.NET Core 包含三个用于处理防伪造令牌的筛选器:

  • ValidateAntiForgeryToken
  • AutoValidateAntiforgeryToken
  • IgnoreAntiforgeryToken
ValidateAntiForgeryToken

​ValidateAntiForgeryToken筛选器要求请求包含有效的防伪令牌,此筛选器可应用于Action、Controller或全局。
  1. [HttpPost]
  2. [ValidateAntiForgeryToken]
  3. public IActionResult Index()
  4. {
  5.     // ...
  6.     return RedirectToAction();
  7. }
复制代码
AutoValidateAntiForgeryToken

​AutoValidateAntiforgeryToken筛选器仅要求不安全的HTTP方法请求包含有效的防伪令牌,以下HTTP方法发出的请求不需要令牌:

  • GET
  • HEAD
  • OPTIONS
  • TRACE
示例:
  1. [AutoValidateAntiforgeryToken]
  2. public class HomeController : Controller
复制代码
全局设置此筛选器:
  1. builder.Services.AddControllersWithViews(options =>
  2. {
  3.     options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
  4. });
复制代码
IgnoreAntiforgeryToken

如果 ValidateAntiForgeryToken 特性应用于控制器,则可以在Action用 IgnoreAntiforgeryToken 特性覆盖它。
​IgnoreAntiforgeryToken筛选器用于消除指定Action或Controller对防伪令牌的要求。此筛选器将覆盖在更高级别指定的 ValidateAntiForgeryToken 和 AutoValidateAntiforgeryToken筛选器。
示例:
  1. [IgnoreAntiforgeryToken]
  2. public IActionResult IndexOverride()
  3. {
  4.     // ...
  5.     return RedirectToAction();
  6. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册