CSRF is a type of web security vulnerability that forces authenticated users to submit unwanted requests to a web application.
It's a way for attackers to manipulate users into performing actions they didn't intend to, often leading to data theft, unauthorized actions, or even complete account compromise.
Simple ASP.NET Core Web Application
![Web Application]()
It has two buttons.
- "Card Details": Uses form to access card details.
- "Make Ajax Call": Access card details with Ajax call.
Here is a simple controller to access user card details.
- The [ValidateAntiForgeryToken] attribute ensures that any request to this action method must include a valid anti-forgery token.
[ValidateAntiForgeryToken]
[HttpPost]
public IActionResult Card(int id)
{
Card card = new Card() { CardNumber = "1234 5678 9012 3456", CVV = "123", ExpiryDate = "12/2022", Name = "John Doe", Id = id };
return View(card);
}
- Enable Antiforgery in ASP.NET Core: Antiforgery middleware is added to the Dependency injection container when one of the following APIs is called in the Program. cs.
- AddMvc
- MapRazorPages
- MapControllerRoute
- AddRazorComponents
- Customize Antiforgery Token: We can customize the anti-forgery token by configuring the anti-forgery options in the Program.cs file.
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = AntiforgeryMiddleware.HeaderName;
options.FormFieldName = AntiforgeryMiddleware.FormFieldName;
});
- Implement Antiforgery token with Cookie: This should now protect your endpoints that are using POST, PUT, and DELETE HTTP verbs.
public class AntiforgeryMiddleware
{
public const string HeaderName = "X-CSRF-TOKEN";
public const string CookieName = "X-CSRF-TOKEN";
public const string FormFieldName = "X-CSRF-TOKEN";
private readonly RequestDelegate _next;
private readonly IAntiforgery _antiforgery;
public AntiforgeryMiddleware(RequestDelegate next, IAntiforgery antiforgery)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_antiforgery = antiforgery;
}
public async Task Invoke(HttpContext context)
{
var tokens = _antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append(CookieName,
tokens.RequestToken!,
new CookieOptions()
{
HttpOnly = false,
//SameSite = SameSiteMode.Strict
});
await _next.Invoke(context);
}
}
- Make AJAX request: This approach helps in situations where forms aren't directly used, like when working with APIs or SPAs (Single Page Applications).
let token = Cookies.get('X-CSRF-TOKEN');
$.ajax({
url: '/card',
type: 'post',
data: {
id: "101",
},
headers: {
"X-CSRF-TOKEN": token
},
success: function (data, status) {
alert("Status: " + status);
},
error: function (data, status) {
alert("Status: " + status);
},
});
Output
![Output]()
Summary
- CSRF attacks trick authenticated users into making requests that they did not intend.
- ASP.NET Core protects against CSRF by using anti-forgery tokens, which must be validated on the server for every POST request.
- For AJAX requests, the token needs to be included in the request headers.
You can access the sample project here GitHub