Preventing CSRF attacks in JSON data posts with anti-forgery tokens in ASP.NET
Posted: (EET/GMT+2)
When you're sending JSON data to your ASP.NET (Core or classic MVC) backend, it's easy to forget that the usual form-based anti-forgery token protections do not automatically apply. CSRF attacks don't care whether you post form data or JSON payloads: they only care if they can get your browser to send a valid request.
Fortunately, you can still use anti-forgery tokens with JSON requests. The trick is to include the token yourself and send it through custom headers.
First, include the token in your Razor/CSHTML view (or even, the template layout):
@Html.AntiForgeryToken()
Then, pick up the token with JavaScript:
const token = document.querySelector("input[name='__RequestVerificationToken']").value;
When making your JSON call, send the token in a header:
fetch("/api/data", {
method: "POST",
headers: {
"Content-Type": "application/json",
"RequestVerificationToken": token
},
body: JSON.stringify({ message: "Hello" }) // your payload here
});
In your controller, require the anti-forgery token using the C# attribute:
[ValidateAntiForgeryToken]
public IActionResult Post([FromBody] MyData data)
{
...
}
Once everything is wired together, your JSON posts are protected just like normal form submissions. It's a small extra step, but well worth doing if your web API is part of a browser-based application.