The page I'm building depends heavily on AJAX. Basically, there is just one "page" and every data transfer is handled via AJAX. Since overoptimistic caching on the browser side leads to strange problems (data not reloaded), I have to perform all requests (also reads) using POST - that forces a reload.
Now I want to prevent the page against CSRF. With form submission, using Html.AntiForgeryToken()
works neatly, but in AJAX-request, I guess I will have to append the token manually? Is there anything out-of-the box available?
My current attempt looks like this:
I'd love to reuse the existing magic. However, HtmlHelper.GetAntiForgeryTokenAndSetCookie
is private and I don't want to hack around in MVC. The other option is to write an extension like
public static string PlainAntiForgeryToken(this HtmlHelper helper)
{
// extract the actual field value from the hidden input
return helper.AntiForgeryToken().DoSomeHackyStringActions();
}
which is somewhat hacky and leaves the bigger problem unsolved: How to verify that token? The default verification implementation is internal and hard-coded against using form fields. I tried to write a slightly modified ValidateAntiForgeryTokenAttribute
, but it uses an AntiForgeryDataSerializer
which is private and I really didn't want to copy that, too.
At this point it seems to be easier to come up with a homegrown solution, but that is really duplicate code.
Any suggestions how to do this the smart way? Am I missing something completely obvious?
Take advantage of anti-forgery tokens in ASP.NET Core to protect users of your applications against cross site request forgery exploits. Who_I_am / Getty Images. Cross-site request forgery (CSRF) is an attack that tricks an end user into executing undesirable actions while logged into a web application.
The URL for the jQuery AJAX call is set to the Controller's action method i.e. /Home/AjaxMethod. The value of the AntiForgery Token and value of the TextBox is passed as parameter and the returned response is displayed using JavaScript Alert Message Box.
You could use the conventional Html.AntiForgeryToken()
helper to generate a hidden field somewhere on the page (not necessarily inside a form) and include it along the ajax request:
var token = $('input[name=__RequestVerificationToken]').val();
$.post(
'/SomeAction', { '__RequestVerificationToken': token },
function() {
alert('Account Deleted.');
}
);
To verify it on the server side:
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult SomeAction()
{
return View();
}
If you have multiple tokens on your page you might need to specify which one to include. As the existing helper generates the hidden fields with the same names it is difficult to make a good selector so you could place them inside spans:
<span id="t1"><%= Html.AntiForgeryToken() %></span>
<span id="t2"><%= Html.AntiForgeryToken() %></span>
and then select the corresponding token:
var token = $('#t1 input[name=__RequestVerificationToken]').val();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With