歡迎光臨
每天分享高質量文章

在 Asp.Net Core WebAPI 中防禦跨站請求偽造攻擊

什麼是跨站請求偽造

跨站請求偽造(英語:Cross-site request forgery),也被稱為 one-click attack 或者 session riding,通常縮寫為 CSRF 或者 XSRF, 是一種挾制用戶在當前已登錄的Web應用程式上執行非本意的操作的攻擊方法。【1】 跟跨網站腳本(XSS)相比,XSS 利用的是用戶對指定網站的信任,CSRF 利用的是網站對用戶網頁瀏覽器的信任。

想瞭解更多,請查看維基百科上的詳細介紹。

使用 Asp.Net Core 內置的 Antiforgery

Asp.Net Core 應用中內置了 Microsoft.AspNetCore.Antiforgery 包來支持跨站請求偽造。如果你的應用取用了 Microsoft.AspNetCore.App 包, 則就已經包含了 Microsoft.AspNetCore.Antiforgery 。如果沒有, 則可以使用下麵的命令來添加這個包:

dotnet add package Microsoft.AspNetCore.Antiforgery

添加了這個包之後, 需要先修改 Startup.cs 檔案中的 ConfigureServices 方法, 添加下麵的配置:

public class Startup {

  public void ConfigureServices(IServiceCollection services) {
    services.AddAntiforgery(options => {
      options.Cookie.SameSite = SameSiteMode.Lax;
      
      options.HeaderName = "X-XSRF-TOKEN";
    });
  }

}

在 SecurityController.cs 檔案中添加一個 Api , 來頒發憑據:

[Route("api/[controller]")]
[ApiController]
public class SecurityController : Controller {

  private IAntiforgery antiforgery;

  public SecurityController(
    IAntiforgery antiforgery
  ) {
    this.antiforgery = antiforgery;
  }

  [HttpGet("xsrf-token")]
  public ActionResult GetXsrfToken() {
    var tokens = antiforgery.GetAndStoreTokens(HttpContext);
    
    
    Response.Cookies.Append(
      "XSRF-TOKEN",
      tokens.RequestToken,
      new CookieOptions {
        HttpOnly = false,
        Path = "/",
        IsEssential = true,
        SameSite = SameSiteMode.Lax
      }
    );
    return Ok();
  }

}

當客戶端請求 ~/api/security/xsrf-token 時, 服務端發送兩個 Cookie :

  • .AspNetCore.Antiforgery.xxxxxx 一個 HTTP Only 的 Cookie , 用於服務端驗證;
  • XSRF-TOKEN 客戶端需要將這個 Cookie 的值用 X-XSRF-TOKEN 的 Header 發送回服務端, 進行驗證;

註意:這兩個 Cookie 不支持跨域請求, 只能在相同的站點內請求, 也是出於安全性方面的考慮。

可以為某一個 ApiController 或者 Action 方法單獨添加 ValidateAntiForgeryTokenAttribute標記來驗證 XSRF-TOKEN, 也可以全域性註冊一個 AutoValidateAntiforgeryTokenAttribute 過濾器來進行自動驗證, 代碼如下:

public class Startup {

  public void ConfigureServices(
    IServiceCollection services,
    IHostingEnvironment env
  ) {
    services.AddMvc(options => {
      
      if (env.IsProduction()) {
        options.Filters.Add(
          new AutoValidateAntiforgeryTokenAttribute()
        );
      }
    });
  }

}

註意問題:不是所有的方法都需要進行 XSRF 認證,除了 GET, HEAD, OPTIONS 和 TRACE 之外的方法才支持 XSRF 認證。

Angular 內置支持

Angular 的 Http 模塊內置支持 XSRF , 前提條件如下:

  • 存在客戶端可以操作的名稱為 XSRF-TOKEN 的 Cookie ;
  • 該 Cookie 不能是 HttpOnly 的, 否則客戶端腳本無法讀取;
  • 該 Cookie 的 Path 必須為 / ;

這三個條件都滿足, 則在向服務端請求時自動發送名稱為 X-XSRF-TOKEN 的 Header , 值則為 XSRF-TOKEN 的 Cookie 的值, 這樣就回自動滿足上面的服務端的設置, 實現自動防禦跨站請求偽造。

已同步到看一看
赞(0)

分享創造快樂