Cross-Site Request Forgery (CSRF)
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.
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,
});
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);
},
});
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