ABP框架系列之五十四:(XSRF-CSRF-Protection-跨站請求偽造保護)


Introduction

"Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious web site, email, blog, instant message, or program causes a user’s web browser to perform an unwanted action on a trusted site for which the user is currently authenticated" (OWASP).

It's also briefly described here to explain how to implement it in ASP.NET Web API.

ABP framework simplifies and automates CSRF protection as much as possible. Startup templates comes with pre-configured and working out of the box. In this document, we will explain how it's integrated to ASP.NET platforms and how it works.

“跨站請求偽造(CSRF)是一種類型的攻擊時,一個惡意網站、電子郵件、博客、即時消息、或程序導致用戶的Web瀏覽器來執行必要的行動在一個受信任的站點,用戶目前認證”(OWASP)。

它也作了簡要的敘述來說明如何實現它在ASP.NET Web API。

ABP框架簡化並自動化CSRF保護盡可能多的。啟動模板附帶預配置和已完成的框。在本文檔中,我們將解釋它是如何集成到ASP.NET平台和它是如何工作的。

Http Verbs

It's not needed to protect our actions for GET, HEAD, OPTIONS and TRACE HTTP verbs since they should be side effect free (don't change database) normally. While ABP assumes that (and implements Anti Forgery protection for only POST, PUT, PATCH and DELETE verbs), you can change this behaviour using attrbiutes defined in this document.

不必保護GET, HEAD, OPTIONS and TRACE這些http謂詞,因為正常情況下應該是無副作用的。(不改變數據庫),ABP假如(實現了POST, PUT, PATCH and DELETE的防偽保護),你可以使用本文檔中的特性改變行為。

Non Browser Clients(非瀏覽器的客戶端

CSRF is a type of attack that is a problem for browsers. Because a browser sends all cookies (including auth cookies) in all requests, including cross domain requests. But, it's not a problem for non browser clients, like mobile applications. ABP framework can understand the difference and automatically skips anti forgery validation for non browser clients.

CSRF攻擊類型,是瀏覽器的問題。因為一個瀏覽器發送的所有cookies(包括認證cookies)在所有的要求,包括跨域請求。但是,對於非瀏覽器客戶來說,這不是問題,比如移動應用程序。ABP框架可以理解這種差異,並自動跳過非瀏覽器客戶端的防偽驗證。

ASP.NET MVC

Features

ASP.NET MVC has it's own built-in AntiForgery system as you probably know. But it has a few weeknesses:

  • Requires to add ValidateAntiForgeryToken attribute to all actions need to be protected. We may forget to add it for all needed actions.
  • ValidateAntiForgeryToken attribute only checks __RequestVerificationToken in the HTML form fields. This makes very hard or impossible to use it for AJAX requests, especially if you are sending "application/json" as content-type. In AJAX requests, it's common to set token in the request header.
  • It's hard to access to the verification token in javascript code (especially if you don't write your javascript in .cshtml files). We need to access it to use it in our AJAX requests.
  • Even we can access to the token in javascript, we should manually add it to the header for every request.

ASP.NET MVC有它自己的內置防偽系統,正如你可能知道的。但是它有幾個薄弱環節:

需要添加validateantiforgerytoken屬性的所有動作都需要被保護。我們可能忘記為所有需要的行動添加它。
validateantiforgerytoken屬性只檢查__requestverificationtoken在HTML表單字段。這很難或不可能將它用於Ajax請求,尤其是當您將“應用程序/ JSON”作為內容類型發送時。在ajax請求中,在請求標頭中設置令牌是很常見的。
使用JavaScript代碼驗證令牌是困難的(尤其是如果你不寫你的JavaScript。cshtml文件)。我們需要訪問它來在Ajax請求中使用它。
即使我們可以用JavaScript訪問令牌,我們也應該手動將它添加到每個請求的報頭中。

ABP does followings to overcome this difficulties:

  • No need to add ValidateAntiForgeryToken attribute for POST, PUT, PATCH and DELETE actions anymore, because they are automatically protected (by AbpAntiForgeryMvcFilter). Automatic protection will be enough for most cases. But you can disable it for an action or controller using DisableAbpAntiForgeryTokenValidation attribute and you can enable it for any action/controller using ValidateAbpAntiForgeryTokenattribute.
  • AbpAntiForgeryMvcFilter also checks token in the header in addition to HTML form field. Thus, we can easily use anti forgery token protection for AJAX requests.
  • Provides abp.security.antiForgery.getToken() function to get the token in the javascript, even you will not need it much.
  • Automatically adds anti forgery token to the header for all AJAX requests.

ABP采取以下措施來克服這些困難:

不需要添加后,validateantiforgerytoken屬性,補丁和刪除動作了,因為他們是自動保護(AbpAntiForgeryMvcFilter)。大多數情況下自動保護就足夠了。但是,您可以禁用它的一個動作或使用disableabpantiforgerytokenvalidation屬性控制器,你可以使它對任何行動/控制器使用validateabpantiforgerytokenattribute。
abpantiforgerymvcfilter還檢查除了HTML表單字段的標題標記。因此,我們可以很容易地使用Ajax請求的防偽令牌保護。
提供ABP。安全。防偽。gettoken()函數在JavaScript得到令牌,即使你不需要它。
為所有Ajax請求自動添加反令牌到報頭。

Thus, it almost seamlessly works.

Integration

Startup templates already integrated to CSRF protection out of the box. If you need to manually add it to your project (maybe you created your project before we added it), follow this guide.

啟動模板已集成CSRF保護開箱。如果需要手動將其添加到項目中(可能在添加項目之前創建了項目),請遵循本指南。

Layout View(布局視圖

We should add the following code in our Layout view:

@{
    SetAntiForgeryCookie();
}

Thus, all pages use this layout will include it. This method is defined in base ABP view class. It creates and sets appropriate token cookies and makes javascript side working. If you have more than one layout, add this to all of them.

That's all we should do for ASP.NET MVC applications. All AJAX requests will work automatically. But we should still use @Html.AntiForgeryToken() HTML helper for our HTML forms which are not posted via AJAX (But no need to ValidateAbpAntiForgeryToken attribute for the corresponding action).

因此,所有使用此布局的頁面都將包含它。這個方法是在基本視圖視圖類中定義的。它創建並設置適當的令牌cookie並使JavaScript側工作。如果您有不止一個布局,請將其添加到所有這些布局中。

這是我們應該做的是ASP.NET的MVC應用程序。所有Ajax請求都將自動工作。但我們仍應使用“HTML。antiforgerytoken() HTML輔助我們的HTML表單不貼通過AJAX(但不需要validateabpantiforgerytoken屬性相應的動作)。

Configuration

XSRF protection is enabled by default. You can disable or configure it in your module's PreInitialize method. Example:

XSRF保護默認情況下啟用。您可以禁用或在你的模塊的配置分發方法。例子:

Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;

You can also configure token and cookie names using Configuration.Modules.AbpWebCommon().AntiForgery object.

ASP.NET Web API

Features

ASP.NET Web API does not include an anti forgery mechanism. ASP.NET Boilerplate provides infrastructure to add CSRF protection for ASP.NET Web API Controllers and completely automates it.

ASP.NET Web API不包括防偽機制。ASP.NET樣板來添加ASP.NET Web API控制器CSRF保護提供了基礎設施和完全自動化。

Integration

With ASP.NET MVC Clients

If you are using Web API inside an MVC project, no additional configuration needed. Even if you are self-hosting your Web API layer in another process, no configuration needed as long as you are making AJAX requests from a configured MVC application.

如果在MVC項目中使用Web API,則不需要額外的配置。即使您在另一個進程中自己托管Web API層,只要您從配置的MVC應用程序中生成Ajax請求,就不需要配置。

With Other Clients

If your clients are diffrent kind of applications (say, an independent angularjs application which can not use SetAntiForgeryCookie() method as described before), then you should provide a way of setting the anti forgery token cookie. One possible way of doing that is to create an api controller like that:

如果你的客戶是不同類型的應用程序(比如說,一個獨立的AngularJS應用不能使用setantiforgerycookie()方法如前所述),那么你應該提供一種方式來設置cookie的防偽標記。這樣做的一種可能的方法是創建像這樣的API控制器:

using System.Net.Http;
using Abp.Web.Security.AntiForgery;
using Abp.WebApi.Controllers;

namespace AngularForgeryDemo.Controllers
{
    public class AntiForgeryController : AbpApiController
    {
        private readonly IAbpAntiForgeryManager _antiForgeryManager;

        public AntiForgeryController(IAbpAntiForgeryManager antiForgeryManager)
        {
            _antiForgeryManager = antiForgeryManager;
        }

        public HttpResponseMessage GetTokenCookie()
        {
            var response = new HttpResponseMessage();

            _antiForgeryManager.SetCookie(response.Headers);

            return response;
        }
    }
}

Then you can call this action from client to set the cookie.

然后,您可以從客戶端調用此操作來設置cookie。

ASP.NET Core

Features

ASP.NET Core MVC has a better Anti Forgery mechanism compared to previous version (ASP.NET MVC 5.x):

  • It has AutoValidateAntiforgeryTokenAttribute class that automates anti forgery validation for all POST, PUT, PATCH and DELETE actions.
  • It has ValidateAntiForgeryToken and IgnoreAntiforgeryToken attributes to control token validation.
  • Automatically adds anti forgery security token to HTML forms if you don't explicitly disable it. So, no need to call @Html.AntiForgeryToken() in most cases.
  • It can read request token from HTTP header and the form field.

ASP.NET核心的MVC具有更好的防偽機制相比以前的版本(ASP.NET MVC 5。x):

它有autovalidateantiforgerytokenattribute類自動化的所有帖子,防偽驗證,補丁和刪除操作。
它有validateantiforgerytoken和IgnoreAntiforgeryToken屬性控制令牌驗證。
如果沒有顯式禁用,則自動向HTML表單添加防偽安全令牌。所以,不需要打”在大多數情況下,antiforgerytoken() HTML。
它可以從HTTP頭和表單字段讀取請求令牌。

ABP adds the following features:

  • Automatically adds anti forgery token to the header for all AJAX requests.
  • Provides abp.security.antiForgery.getToken() function to get the token in the javascript, even you will not need it much.
  • ABP增加了以下功能:

    為所有Ajax請求自動添加反令牌到報頭。
    提供ABP。安全。防偽。gettoken()函數在JavaScript得到令牌,即使你不需要它。

Integration

Startup templates already integrated to CSRF protection out of the box. If you need to manually add it to your project (maybe you created your project before we added it), follow this guide.

啟動模板已綜合CSRF保護開箱。如果需要手動將其添加到項目中(可能在添加項目之前創建了項目),請遵循本指南。

Startup Class

First, we should add AutoValidateAntiforgeryTokenAttribute to global filters while adding MVC in ConfigureServices of Startup class:

services.AddMvc(options =>
{
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});

Thus, all MVC actions (except GET, HEAD, OPTIONS and TRACE as declared before) will be automatically validated for anti forgery token.

Layout View

We should add the following code in our Layout view:

@using Abp.Web.Security.AntiForgery
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@{
    AbpAntiForgeryManager.SetCookie(Context);
}

Thus, all pages use this layout will include it. It creates and sets appropriate token cookies and makes javascript side working. If you have more than one layout, add this to all of them.

That's all we should do for ASP.NET Core MVC applications. All AJAX requests will work automatically. For non-ajax form submits, ASP.NET Core automatically adds anti forgery token field if you use one of asp-* tags in your form. So, no need to use @Html.AntiForgeryToken() normally.

因此,所有使用此布局的頁面都將包含它。它創建並設置適當的令牌cookie並使JavaScript側工作。如果您有不止一個布局,請將其添加到所有這些布局中。

這是我們應該做的是ASP.NET核心的MVC應用程序。所有Ajax請求都將自動工作。非Ajax表單提交,ASP.NET核心自動添加防偽標記領域,如果你使用一個ASP *標簽在表單。因此,沒有必要使用“HTML antiforgerytoken()正常。

Client Libraries(客戶端庫

Anti forgery token should be provided in the request header for all AJAX requests, as we declared before. We will see how it's done here.

如我們前面聲明的那樣,在請求標頭中為所有Ajax請求提供反偽造令牌。我們來看看它是怎么做的。

jQuery

abp.jquery.js defines an AJAX interceptor which adds the anti forgery token to the request header for every request. It gets the token from abp.security.antiForgery.getToken() javascript function.

abp.jquery.js定義為每個請求的請求標頭添加防偽標記一個Ajax攔截。它從總部得到令牌。安全。防偽gettoken() JavaScript函數。

Angular

Angular automatically adds the anti forgery token to all AJAX requests. See Cross Site Request Forgery (XSRF) Protection section in Angularjs $http document. ABP uses the same cookie and header names as default. So, Angular integration works out of the box.

Angular自動添加反令牌令牌到所有Ajax請求。看到跨站請求偽造(XSRF)在AngularJS $HTTP文檔保護部分。ABP使用相同的cookie和頭名稱作為默認值。這樣,Angular集成可以使用了。

Other Libraries

If you are using any other library for AJAX requests, you have three options:

Intercept XMLHttpRequest(攔截XMLHttpRequest

Since all libraries use the javascript's native AJAX object, XMLHttpRequest, you can define such a simple interceptor to add token to the header:

因為所有的庫都使用JavaScript的原生Ajax對象,XMLHttpRequest,你可以定義這樣一個簡單的攔截添加令牌的頭:

(function (send) {
    XMLHttpRequest.prototype.send = function (data) {
        this.setRequestHeader(abp.security.antiForgery.tokenHeaderName, abp.security.antiForgery.getToken());
        return send.call(this, data);
    };
})(XMLHttpRequest.prototype.send);
Use Library Interceptor(使用庫的攔截

A good library provide interception points (like jquery and angularjs). So, follow your vendor's documentation to learn how to intercept requests and manipulate headers.

一個好的庫提供攔截點(如jQuery和AngularJS)。因此,遵循您的供應商的文檔來學習如何攔截請求和處理頭文件。

Add the Header Manually(手動添加Header

The last option, you can use abp.security.antiForgery.getToken() to get the token and add to the request header manually for every request. But you probably do not need this and solve the problem as descibed above.

最后一個選項,你可以使用ABP。安全。防偽。gettoken()獲得令牌和添加手動為每個請求的請求頭。但你可能不需要這個和上面解決問題了。

Internals(內部

You may wonder how ABP handles it. Actually, we are using the same mechanism described in the angularjs documentation mentioned before. ABP stores the token into a cookie (as described above) and sets requests headers using that cookie. It also well integrates to ASP.NET MVC, Web API and Core frameworks for validating it.

你可能想知道ABP如何處理它。實際上,我們使用的是在AngularJS文檔之前提到的描述相同的機制。ABP將令牌存儲到cookie中(如上所述),並使用該cookie設置請求頭。它還集成了ASP.NET的MVC,驗證它的Web API和核心框架。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM