Asp.net

ASP.net MVC AntiForgeryToken over AJAX

  • October 11, 2019

我目前正在 ASP.net 中開發一個 MVC 應用程序。我正在使用 AJAX.ActionLink 在記錄列表中提供刪除連結,但是這是非常不安全的。我已經把這個:

<AcceptVerbs(HttpVerbs.Post)>

在函式上執行刪除,這會阻止函式被 URL 簡單地呼叫。但是,仍然存在的另一個安全漏洞是,如果我要使用此內容製作一個基本的 html 頁面:

<form action="http://foo.com/user/delete/260" method="post">
<input type="submit" />
</form>

它仍然會執行一個文章,但來自不同的位置。

是否可以將 AntiForgeryToken 與 AJAX ActionLink 一起使用?如果是這樣,這是一種安全的方法嗎?還有更多我沒有意識到的安全漏洞嗎?

看看這篇博文

假設你有一個像這樣的 Action 方法:

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] public ActionResult DeleteAccount(int accountId) { // delete stuff }

你通過以下方式呼叫它:

$.post('/home/DeleteAccount', { accountId: 1000 }, function() { alert('Account Deleted.'); });

由於 POST 不包含 AntiForgeryToken,它會失敗。

幸運的是,解決這個問題並不需要太多的腦力。AntiForgeryToken 的所有客戶端組件所做的就是將令牌放在一個基本的隱藏欄位中。因此,您只需提取該數據並將其包含在您的 AJAX 呼叫中。

var token = $('input[name=__RequestVerificationToken]').val();

$.post('/home/DeleteAccount', { accountId: 1000, '__RequestVerificationToken': token }, function() { alert('Account Deleted.'); });

請注意,如果頁面上有多個帶有多個 AntiForgeryToken 的表單,則必須在 jQuery 選擇器中指定您想要的表單。另一個問題是,如果您使用 jQuery 的 serializeArray()函式,則必須添加一些不同的內容:

var formData = $('#myForm').serializeArray(); var token = $('input[name=__RequestVerificationToken]').val(); formData.push({ name: '__RequestVerificationToken', value: token });

$.post('/home/DeleteAccount', formData, function() { alert('Account Deleted.'); });

更新:連結已修復。

您可以將 AntiForgeryToken 與 Ajax.ActionLink 一起使用,但您需要手動將 AntiForgeryToken 插入到請求的標頭中,如下所示:

function GetAntiForgeryToken(){
  var tokenWindow = window;
  var tokenName = "__RequestVerificationToken";
  var tokenField = $(tokenWindow.document).find("input[type='hidden'][name='" +     tokenName +   "']");
  if (tokenField.length == 0) {return null;}
  else {
     return {
        name: tokenName,
        value: tokenField.val()
     };
  }
};

然後,我們可以使用 $.ajaxPrefilter 將其插入到標題中:

$.ajaxPrefilter(
  function (options, localOptions, jqXHR) {
     var token = GetAntiForgeryToken();
     jqXHR.setRequestHeader(token.name, token.value);
  }
);

我在這裡寫了一篇關於它的文章。希望這可以幫助!

引用自:https://stackoverflow.com/questions/1346070