使用 Windows 驗證時,應用程式端點必須受到保護,以防止 CSRF 攻擊的方式與針對 cookie s 執行的方式相同。 瀏覽器會隱含地將驗證內容傳送至伺服器,因此端點必須受到保護,以防止 CSRF 攻擊。
跨網站偽造要求 (也稱為 XSRF 或 CSRF) 是針對 Web 裝載應用程式的攻擊,惡意 Web 應用程式可能會影響用戶端瀏覽器與信任該瀏覽器的 Web 應用程式之間的互動。 這些攻擊是可行的,因為網頁瀏覽器會隨著每個要求自動傳送某些類型的驗證權杖給網站。 這種惡意探索形式也稱為 單鍵攻擊 或 會話, 因為攻擊會利用使用者先前驗證的會話。
以 AJAX 要求形式傳送表單提交。
使用 CSS 隱藏表單。
這些替代案例不需要一開始流覽惡意網站以外的使用者的任何動作或輸入。
使用 HTTPS 不會防止 CSRF 攻擊。 惡意網站可以 https://www.good-banking-site.com/
像傳送不安全的要求一樣輕鬆傳送要求。
某些攻擊會以回應 GET 要求的端點為目標,在此情況下,可以使用影像標籤來執行動作。 這種攻擊形式常見於允許影像但封鎖 JavaScript 的論壇網站上。 變更 GET 要求狀態的應用程式,其中變數或資源遭到改變,很容易遭受惡意攻擊。 變更狀態不安全的 GET 要求。 最佳做法是永遠不會變更 GET 要求的狀態。
CSRF 攻擊適用于用於 cookie 驗證的 Web 應用程式,因為:
網頁應用程式所發出的瀏覽器存放區 cookie 。
已 cookie 儲存的 包含已驗證使用者的會話 cookie 。
瀏覽器會將與網域相關聯的所有 cookie 專案傳送至 Web 應用程式,不論對應用程式的要求在瀏覽器中產生的方式為何。
不過,CSRF 攻擊不限於惡意探索 cookie 。 例如,基本和摘要式驗證也很容易遭受攻擊。 當使用者使用基本或摘要式驗證登入之後,瀏覽器會自動傳送認證,直到會話結束為止。
在此內容中, 會話 是指使用者進行驗證的用戶端會話。 與伺服器端會話或ASP.NET Core會話中介軟體無關。
使用者可以採取預防措施來防範 CSRF 弱點:
使用 Web 應用程式完成時登出。
定期清除瀏覽器 cookie 。
不過,CSRF 弱點基本上是 Web 應用程式的問題,而不是使用者。
驗證基本概念
Cookie型驗證是常用的驗證形式。 權杖型驗證系統越來越受歡迎,特別是單頁應用程式 (SPA) 。
Cookie型驗證
當使用者使用其使用者名稱和密碼進行驗證時,會發出權杖,其中包含可用於驗證和授權的驗證票證。 權杖會儲存為 cookie 隨用戶端提出之每個要求一起傳送的 。 驗證中介軟體會 Cookie 執行產生和驗證此 cookie 動作。 中介軟體會將使用者主體序列化為加密 cookie 的 。 在後續的要求中,中介軟體會 cookie 驗證 、重新建立主體,並將主體指派給 HttpContext.User 屬性。
權杖式驗證
使用者經過驗證時,會 (不是反分叉權杖) 發出權杖。 權杖包含宣告形式的使用者 資訊,或 參考權杖,將應用程式指向應用程式中維護的使用者狀態。 當使用者嘗試存取需要驗證的資源時,權杖會以持有人權杖的形式傳送至具有額外授權標頭的應用程式。 此方法可讓應用程式變成無狀態。 在每個後續要求中,權杖會傳入伺服器端驗證的要求中。 此權杖未 加密;其 已編碼。 在伺服器上,權杖會解碼以存取其資訊。 若要在後續要求上傳送權杖,請將權杖儲存在瀏覽器的本機儲存體中。 如果權杖儲存在瀏覽器的本機儲存體中,請不要擔心 CSRF 弱點。 當令牌儲存在 cookie 中時,CSRF 是一個考慮。 如需詳細資訊,請參閱 GitHub 問題 SPA 程式代碼範例會新增兩 cookie 個 。
裝載于一個網域的多個應用程式
共用主機環境很容易遭受會話攔截、登入 CSRF 和其他攻擊。
雖然 example1.contoso.net
和 example2.contoso.net
是不同的主機,但在網域下的 *.contoso.net
主機之間會有隱含信任關係。 此隱含信任關係可讓可能不受信任的主機影響彼此 cookie (控管 AJAX 要求的相同原始原則不一定適用于 HTTP cookie) 。
在裝載于相同網域的應用程式之間惡意探索受信任 cookie s 的攻擊,可以藉由不共用網域來防止攻擊。 當每個應用程式裝載于自己的網域時,不會隱含 cookie 信任關係來惡意探索。
ASP.NET Core反forgery 組態
ASP.NET Core使用ASP.NET Core 資料保護來實作反移轉。 資料保護堆疊必須設定為在伺服器陣列中運作。 如需詳細資訊,請參閱 設定資料保護。
在 中 Startup.ConfigureServices
呼叫下列其中一個 API 時,反移轉中介軟體會新增至相依性插入容器:
AddMvc
MapRazorPages
MapControllerRoute
MapBlazorHub
在 ASP.NET Core 2.0 或更新版本中,FormTagHelper會將反forgery 權杖插入 HTML 表單元素中。 檔案中的 Razor 下列標記會自動產生反分叉權杖:
<form method="post">
</form>
同樣地,如果表單的 方法不是 GET, IHtmlHelper.BeginForm 則預設會產生反移轉權杖。
當標記包含 method="post"
屬性且下列任一項為 true 時 <form>
,就會自動產生 HTML 表單元素的反分叉標記:
動作屬性是空的 (action=""
) 。
動作屬性未提供 (<form method="post">
) 。
可以停用自動產生 HTML 表單元素的反分叉標記:
使用 屬性明確停用反forgery 權杖 asp-antiforgery
:
<form method="post" asp-antiforgery="false">
</form>
表單元素是使用標籤協助程式退出宣告標籤協助程式 ! 退出宣告符號:
<!form method="post">
</!form>
FormTagHelper
從檢視中移除 。 FormTagHelper
您可以將下列指示詞新增至 Razor 檢視,以從檢視中移除 :
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Razor 頁面會自動受到 XSRF/CSRF 的保護。 如需詳細資訊,請參閱 XSRF/CSRF 和 Razor 頁面。
防禦 CSRF 攻擊最常見的方法是使用 同步器權杖模式 (STP) 。 當使用者要求具有表單資料的頁面時,會使用 STP:
伺服器會將與目前使用者的身分識別相關聯的權杖傳送給用戶端。
用戶端會將權杖傳回伺服器以進行驗證。
如果伺服器收到不符合已驗證使用者身分識別的權杖,則會拒絕要求。
權杖是唯一且無法預測的。 權杖也可以用來確保一系列要求 (的適當排序,例如確保要求順序為:第 1 > 頁 2 > 頁 3) 。 ASP.NET Core MVC 和 Razor Pages 範本中的所有表單都會產生反移轉權杖。 下列一組檢視範例會產生反移轉權杖:
<form asp-controller="Todo" asp-action="Create" method="post">
</form>
@using (Html.BeginForm("Create", "Todo"))
使用 HTML 協助程式使用標籤協助程式 @Html.AntiForgeryToken
,明確地將反分叉標記新增至 <form>
元素:
<form action="/" method="post">
@Html.AntiForgeryToken()
</form>
在上述每個案例中,ASP.NET Core新增類似下列範例的隱藏表單欄位:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core包含三個篩選準則,可用於反forgery 權杖:
ValidateAntiForgeryToken
AutoValidateAntiforgeryToken
IgnoreAntiforgeryToken
反forgery 選項
在 中 Startup.ConfigureServices
自訂 AntiforgeryOptions :
services.AddAntiforgery(options =>
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
使用 類別的屬性 CookieBuilder 設定反分叉 Cookie
屬性,如下表所示。
如需詳細資訊,請參閱CookieAuthenticationOptions。
IAntiforgery 提供 API 來設定反Forgery 功能。 IAntiforgery
可以在 類別的 Startup
方法中 Configure
要求。
在下例中︰
來自應用程式首頁的中介軟體可用來產生反分叉權杖,並在回應中以 的形式 cookie 傳送它。
要求權杖會以 JavaScript 可讀取 cookie 的方式傳送,並使用Angular JS一節中所述的預設Angular命名慣例。
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
app.Use(next => context =>
string path = context.Request.Path.Value;
if (string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
return next(context);
需要反分叉驗證
ValidateAntiForgeryToken 是可套用至個別動作、控制器或全域的動作篩選。 除非要求包含有效的反Forgery 權杖,否則對套用此篩選動作的要求會遭到封鎖。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
var result =
await _userManager.RemoveLoginAsync(
user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
return RedirectToAction(nameof(ManageLogins), new { Message = message });
屬性 ValidateAntiForgeryToken
需要權杖來要求其標記的動作方法,包括 HTTP GET 要求。 ValidateAntiForgeryToken
如果屬性套用至應用程式的控制器,可以使用 屬性覆寫 IgnoreAntiforgeryToken
。
ASP.NET Core不支援自動將反分叉權杖新增至 GET 要求。
僅針對不安全的 HTTP 方法自動驗證反分叉權杖
ASP.NET Core應用程式不會針對 GET、HEAD、OPTIONS 和 TRACE) (安全 HTTP 方法產生反分叉權杖。 您可以使用AutoValidateAntiforgeryToken屬性,而不是廣泛套用 ValidateAntiForgeryToken
屬性,然後以屬性覆 IgnoreAntiforgeryToken
寫該屬性。 此屬性的運作方式 ValidateAntiForgeryToken
與 屬性相同,不同之處在于它不需要權杖來取得使用下列 HTTP 方法提出的要求:
OPTIONS
TRACE
建議您廣泛地針對非 API 案例使用 AutoValidateAntiforgeryToken
。 此屬性可確保 POST 動作預設受到保護。 除非套用至個別動作方法, ValidateAntiForgeryToken
否則替代方法是預設忽略反分機權杖。 在此案例中,POST 動作方法可能會遭到錯誤保護,讓應用程式容易遭受 CSRF 攻擊。 所有 POST 都應該傳送反分叉權杖。
API 沒有自動機制可傳送非 cookie 部分的權杖。 實作可能取決於用戶端程式代碼實作。 以下顯示一些範例:
類別層級範例:
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
全域範例:
services.AddControllersWithViews(options =>
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
覆寫全域或控制器反分叉屬性
IgnoreAntiforgeryToken篩選準則可用來消除指定動作 (或控制器) 的反forgery 權杖需求。 套用時,此篩選會 ValidateAntiForgeryToken
覆寫和 AutoValidateAntiforgeryToken
篩選在全域或控制器) 上指定于較高層級 (。
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
// no antiforgery token required
驗證後重新整理權杖
將使用者重新導向至檢視或 Razor 頁面頁面,在使用者經過驗證之後,應該重新整理權杖。
JavaScript、AJAX 和 SPA
在傳統 HTML 型應用程式中,反分叉權杖會使用隱藏的表單欄位傳遞至伺服器。 在以新式 JavaScript 為基礎的應用程式和 SPA 中,許多要求都是以程式設計方式提出。 這些 AJAX 要求可能會使用其他技術 (,例如要求標頭或 cookie s) 來傳送權杖。
如果使用 cookie 來儲存驗證權杖,以及在伺服器上驗證 API 要求,CSRF 是潛在的問題。 如果使用本機儲存體來儲存權杖,CSRF 弱點可能會降低,因為本機儲存體的值不會隨著每個要求自動傳送到伺服器。 建議使用本機儲存體在用戶端上儲存反Forgery 權杖,並將權杖傳送為要求標頭。
JavaScript
使用 JavaScript 搭配檢視時,可以使用檢視中的服務來建立權杖。 將 IAntiforgery 服務插入檢視,並呼叫 GetAndStoreTokens :
ViewData["Title"] = "AJAX Demo";
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
return Xsrf.GetAndStoreTokens(Context).RequestToken;
<input type="hidden" id="RequestVerificationToken"
name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<div class="row">
<p><input type="button" id="antiforgery" value="Antiforgery"></p>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == XMLHttpRequest.DONE) {
if (xhttp.status == 200) {
alert(xhttp.responseText);
} else {
alert('There was an error processing the AJAX request.');
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("antiforgery").onclick = function () {
xhttp.open('POST', '@Url.Action("Antiforgery", "Home")', true);
xhttp.setRequestHeader("RequestVerificationToken",
document.getElementById('RequestVerificationToken').value);
xhttp.send();
</script>
這種方法不需要直接從伺服器處理 設定 cookie ,或從用戶端讀取它們。
上述範例會使用 JavaScript 讀取 AJAX POST 標頭的隱藏欄位值。
JavaScript 也可以存取 中的 cookie 權杖,並使用 cookie 的內容來建立具有權杖值的標頭。
context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken,
new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });
假設腳本要求在名為 X-CSRF-TOKEN
的標頭中傳送權杖,請設定反forgery 服務來尋找 X-CSRF-TOKEN
標頭:
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
下列範例會使用 JavaScript 來提出具有適當標頭的 AJAX 要求:
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
return "";
var csrfToken = getCookie("CSRF-TOKEN");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 204) {
alert('Todo item is created successfully.');
} else {
alert('There was an error processing the AJAX request.');
xhttp.open('POST', '/api/items', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "name": "Learn C#" }));
AngularJS
JSAngular會使用慣例來處理 CSRF。 如果伺服器傳送 cookie 名稱 XSRF-TOKEN
為 的 ,Angular JS$http
服務會在將要求傳送至伺服器時,將值新增 cookie 至標頭。 此程式是自動的。 用戶端不需要明確設定標頭。 標頭名稱為 X-XSRF-TOKEN
。 伺服器應該偵測到此標頭,並驗證其內容。
若要讓 ASP.NET Core API 在應用程式啟動時使用此慣例:
將您的應用程式設定為在名為 XSRF-TOKEN
的 cookie 中提供權杖。
設定反分叉服務來尋找名為 X-XSRF-TOKEN
的標頭,這是Angular傳送 XSRF 權杖的預設標頭名稱。
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
app.Use(next => context =>
string path = context.Request.Path.Value;
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
return next(context);
public void ConfigureServices(IServiceCollection services)
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Windows 驗證和反forgery cookie s
使用 Windows 驗證時,應用程式端點必須受到保護,以防止 CSRF 攻擊的方式與針對 cookie s 執行的方式相同。 瀏覽器會隱含地將驗證內容傳送至伺服器,因此端點必須受到保護,以防止 CSRF 攻擊。
擴充反分叉
此 IAntiforgeryAdditionalDataProvider 類型可讓開發人員透過往返每個權杖中的其他資料,擴充反 CSRF 系統的行為。 GetAdditionalData每次產生欄位權杖時都會呼叫 方法,而且傳回值會內嵌在產生的權杖中。 實作者可以傳回時間戳記、nonce 或任何其他值,然後在驗證權杖時呼叫 ValidateAdditionalData 來驗證此資料。 用戶端的使用者名稱已內嵌在產生的權杖中,因此不需要包含這項資訊。 如果權杖包含補充資料,但未 IAntiForgeryAdditionalDataProvider
設定任何補充資料,則不會驗證補充資料。
在 Web 伺服陣列上裝載 ASP.NET Core