防范跨網站請求偽造 (XSRF/CSRF) 攻擊
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會在頁面中添加隱藏的表單域,其包含了防偽令牌:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
發送表單請求時,將防偽令牌添加到表單字段或添加到RequestVerificationToken請求頭發送給服務器。當請求標頭和表單有效負載中都提供了防偽造令牌時,僅驗證標頭中的令牌。
另一種方式是服務器將防偽令牌添加到cookie中,客戶端從cookie中讀取防偽令牌添加到請求頭發送請求。
?
ASP.NET Core 中的防偽造
在Program.cs中調用以下 API 之一時,防偽造中間件將自動添加到容器:
?
最小API添加防偽造中間件
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
?ValidateAntiForgeryToken篩選器要求請求包含有效的防偽令牌,此篩選器可應用于Action、Controller或全局。
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
AutoValidateAntiForgeryToken
?AutoValidateAntiforgeryToken篩選器僅要求不安全的HTTP方法請求包含有效的防偽令牌,以下HTTP方法發出的請求不需要令牌:
- GET
- HEAD
- OPTIONS
- TRACE
示例:
[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();
}
本文來自博客園,作者:-YADA-,轉載請注明原文鏈接:http://www.rzrgm.cn/yada/p/19037102

浙公網安備 33010602011771號