Sunday, 22 September 2024

Cross-Site Request Forgery (CSRF) in ASP.NET Core

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, //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); }, });


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

Tuesday, 27 August 2024

Understanding the Flag Enums in C#

 

Flags Enum Attribute

  1. Use the [Flags] attribute to represent the enum as a bit field.
  2. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value. Such collections are often used with bitwise operators.
[Flags]
public enum SignalColor
{
    None = 0,//0000
    Red = 1,//0001
    Green = 2,//0010
    Yellow = 4,//0100
    Stop = Red | Yellow//0101
}
public class FlagsEnum
{
    public static void Test()
    {
        //SignalColor.Stop & SignalColor.Red == SignalColor.Red
        if (SignalColor.Stop.HasFlag(SignalColor.Red))
        {
            Console.WriteLine("Red is to stop");
        }
    }
}


Explanation of the above code

  1. The value of SignalColor.Stop is 0101 in binary (which is 5 in decimal).
  2. The value of SignalColor.Red is 0001 in binary (which is 1 in decimal).

When you perform a bitwise AND operation between SignalColor.Stop (0101) and SignalColor.Red (0001), the result is.

  • 0101 (Stop)
  • 0001 (Red)

Result

0001 (which equals SignalColor.Red)

Summary

The SignalColor enum uses the [Flags] attribute to represent a combination of signal colors using bitwise operations.

Friday, 28 January 2022

DevExpress DataGrid - Add columns dynamically

This example demonstrates the DataGrid UI component communicating with a Web API service and allows to add columns dynamically.

  1. Create a CustomStore
  2. Make a call to API controller
  3. Process the controller response 
  4. Add columns dynamically in "onLoaded"


var dataGrid;
var responseData;
var col = new Array();

let customDataSource = new DevExpress.data.CustomStore({
key: "ID",
load: function (loadOptions) {
var deferred = $.Deferred();
$.ajax({
url: "/DataWorkbench/GetClientModel",
method: "GET"
})
.done(function (response) {
responseData = response;
deferred.resolve(JSON.parse(response.data), {
totalCount: response.totalCount
})
})
.fail(function (e) {
deferred.reject("Insertion failed");
});
return deferred.promise();
},
onLoaded: function (result) {

for (let i = 0; i < responseData.columns.length; i++) {
dataGrid.addColumn(responseData.columns[i]);
}
}
});



$(function () {

$("#gridContainer").dxDataGrid({
dataSource: customDataSource,
remoteOperations: true,
showBorders: true,
editing: {
mode: 'cell',
allowUpdating: true,
allowAdding: true,
allowDeleting: true,
},
customizeColumns: function (columns) {
columns[0].visible = false;

},
columns:[]
})

dataGrid = $("#gridContainer").dxDataGrid("instance");
});