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

在 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)

分享創造快樂