ASP.NET 核心執行跨網站請求準備 (XSRF/CSRF) 對策

更新頁 :
頁面創建日期 :

環境

Visual Studio
  • Visual Studio 2019
ASP.NET酷
  • 3.0
  • 3.1

什麼是跨網站請求偽造?

跨網站請求偽造 (CSRF/XSRF) 僅在原始目標網站中處理, 對從外部網站等執行更新處理等的漏洞的攻擊。

例如,您能夠在網站上發表評論。 通常,您將從該網站輸入評論併發佈。 在大多數情況下,此發送過程將數據發送到目標 URL 進行處理。

因此,如果您從目標網站以外的網站向 URL 發送類似的數據, 與發表評論相同。

如果只有攻擊者這樣做,它就不會成為太大的威脅。 CSRF 的可怕之處在於,攻擊者通過建構模擬網站或將隱藏的網址 嵌入到網站中來 其他用戶無意中訪問它,然後成為攻擊者。

我們不會在這裡進行深入討論,因此請查看跨網站請求偽造的詳細資訊。

ASP.NET Core 將此功能整合到框架中。

查看跨網站請求偽造的工作原理

嘗試查看更新過程是否實際從外部網站或工具執行。

在 Index.cshtml 中,創建一個輸入表單,該表單將輸入的文本發送到伺服器。 然後,放置ViewData以顯示伺服器為輸入文本創建的消息。

Index.cshtml

@{
  ViewData["Title"] = "Home Page";
}

<div class="text-center">
  <h1 class="display-4">Welcome</h1>
  <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<form method="post">
  <input type="text" name="text" />
  <button type="submit">送信</button>
</form>

<p>@ViewData["Message"]</p>

伺服器端HomeController.cs處理發送的文本並將其輸出到 Visual Studio 追蹤中。 將相同的文本設置為ViewData,以便用戶端可以顯示它們。

HomeController.cs

public class HomeController : Controller
{
  // 省略

  [HttpPost]
  public IActionResult Index(string text)
  {
    System.Diagnostics.Trace.WriteLine($"「{text}」が入力されました。");
    ViewData["Message"] = $"「{text}」が入力されました。";
    return View();
  }

  // 省略
}

嘗試以正常方式完成您建立的功能。 執行調試運行並在螢幕出現時輸入文本,然後按兩下「提交」按鈕。

螢幕上將顯示您期望的已處理文本。

由於跟蹤也列印,因此文本也顯示在 Visual Studio 的輸出視窗中。 實際上,我們執行一些操作,例如在資料庫中註冊輸入數據,但為了簡化代碼,我們省略了輸入數據。

現在,嘗試在調試程式時從目標網站外部訪問它。 為了簡化實現,我們將使用名為 Visual Studio 代碼的工具發送 POST。 如果可以發送 POST,則可以安全地使用其他工具或為攻擊構建單獨的網站程式。

從 Visual Studio Code 安裝名為REST 用戶端的延伸 只需打開 .HTTP 檔,即可輕鬆驗證 REST API 的行為。

在文字檔案中建立 .http 檔,並在 Visual Studio Code 中開啟該檔案,如下所示: 您可以透過按下「發送請求」來發送 GET 或 POST。

創建以下 POST 資料時,將在螢幕上輸入文本,然後按「發送」按鈕發送幾乎等效的數據。 (本地主機的埠號應適合執行環境。

RestTest.HTTP

### Form で POST 送信
POST https://localhost:44372/home/index HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="text"

なんらかのテキスト
------WebKitFormBoundary7MA4YWxkTrZu0gW--

傳送時,您可以看到伺服器端正在接收和處理文本。

Visual Studio Code 端可以獲取結果。 如果您仔細查看結果代碼,您將看到 ViewData 中設置的值。 ( 在 Unicode 中顯示,但在 Web 瀏覽器中正確顯示文字 )

處理跨網站要求偽造漏洞

正如我在開頭提到的,ASP.NET Core 包含了針對跨網站請求偽造的對策。 常見的對策是,在需要 POST 的螢幕上,必須提前向用戶端頒發唯一令牌。 除非將權杖發送到伺服器,否則不接受該權杖。

當然,如果您直接從外部網站訪問 URL,則不接受權杖,因為令牌未知。

首先,我們是關於如何向用戶端 (HTML) 頒發權杖,但實際上,這是框架的自動方法。 我會去的 在格式標記中指定 POST 方法等,以在 HTML 中包括權杖參數。

在下圖中的 HTML 中,輸入名稱 = "__RequestVerificationToken" type="隱藏"部分。 按下「發送」按鈕時,這一次一起發送到伺服器。 順便說一下,GET 方法不附加它。

對於伺服器端,服務為Startup.cs。 AddControllers WithViews 方法的選項。 到過濾器 只需設定AutoValidateAntiforgeryTokenAttribute,所有操作 此令牌檢查將自動添加到 POST、PUT、PATCH 和 DELETE HTTP 方法中。

如果要將此限制附加到特定操作(而不是所有操作),請為每個控制器或每個操作添加此約束。 也可以設置。

相反,您希望對大多數操作施加約束,但您希望排除特定操作。 將 IgnoreAntiforgeryToken屬性設置為控制器和操作,這是可以的。

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllersWithViews(options =>
  {
    // 全ての「POST, PUT, PATCH, DELETE」アクションに自動で ValidateAntiForgeryToken を付与。
    // 個別に除外したい場合は「IgnoreAntiforgeryToken」属性を指定すること
    // API では HTML 側にトークンを発行できないのでコントローラーに「IgnoreAntiforgeryToken」を指定する必要がある。
    options.Filters.Add(new Microsoft.AspNetCore.Mvc.AutoValidateAntiforgeryTokenAttribute());
  });
}

現在,讓我們看看它是如何工作的。 首先,通常從螢幕執行傳輸過程。

結果按預期反映在螢幕上。

還列印到跟蹤。

現在,嘗試從外部訪問它。

已訪問,但返回了壞請求。 與沒有措施的結果不同。 您會發現它受到保護,因為它未輸出到跟蹤中。

總結

這一次,我們採取了措施,反對跨網站請求偽造。 實現非常簡單,因為框架已經內置了它。

構建網站需要 CSRF 以外的許多漏洞防護。 或者,您可以使用 OWASP 等工具檢查網站中的漏洞。