Monday 3 August 2020

How to get out of CSRF attack by securing your AJAX requests by passing AntiForgeryToken

Why do we need Anti-Forgery Tokens

To help prevent CSRF attacks, ASP.NET MVC uses anti-forgery tokens, also called request verification tokens.

1.     The client requests an HTML page that contains a form.

2.     The server includes two tokens in the response. One token is sent as a cookie. The other is placed in a hidden form field. The tokens are generated randomly so that an adversary cannot guess the values.

3.     When the client submits the form, it must send both tokens back to the server. The client sends the cookie token as a cookie, and it sends the form token inside the form data. (A browser client automatically does this when the user submits the form.)

4.     If a request does not include both tokens, the server disallows the request.

 

Adding an Anti-Forgery Tokens is straight forward and easy To add the anti-forgery tokens to a Razor page, we can use the HtmlHelper.AntiForgeryToken helper method:

 Example:

 @using (Html.BeginForm("Create", "Customer")) {

    @Html.AntiForgeryToken()

}

 But in many cases programmers use AJAX to post data to server. an AJAX request might send JSON data, not HTML form data therefore the normal     @Html.AntiForgeryToken() method has nothing to do here so we need to use another workaround to fix this issue.

 If we are looking behind the scenes in Asp.Net MVC when we use @Html.AntiForgeryToken() Razor creates a hidden input field with name __RequestVerificationToken to store tokens.

 Here is an example html of hidden token

 <form action="/Customer/Create" method="post">

    <input name="__RequestVerificationToken" type="hidden"  

           value="6fGBtLZmVBZ59oUad1Fr33BuPxANKY9q3Srr5y[...]" />   

    <input type="submit" value="Submit" />

</form>

 

The work around is to Get the token before sending ajax request and Pass the token in the AJAX call.

 Step 1:

 var token = $('input[name="`__RequestVerificationToken`"]').val();

 Step 2:

 function createCustomer() {

 var customer = {     
    "FirstName": $('#fName').val(),
    "LastName": $('#lName').val(),
    "Email": $('#email').val(),
    "Phone": $('#phone').val(),
}; 
$.ajax({
    url: '/Customer/Create
    type: 'POST',
    data: { 
     __RequestVerificationToken:token,
     student: student,
        },
    dataType: 'JSON',
    contentType:'application/x-www-form-urlencoded; charset=utf-8',
    success: function (response) {
        if (response.result == "Success") {
            alert(Customer Created Succesfully!')
         }
    },
    error: function (x,h,r) {
        alert('Something went wrong')
      }
})
};
  
In the above example we are sending it via the data part of ajax request. We can also send it through header. 
 <script>

    @functions{

        public string TokenHeaderValue()

        {

            string cookieToken, formToken;

            AntiForgery.GetTokens(null, out cookieToken, out formToken);

            return cookieToken + ":" + formToken;               

        }

    }

 

    $.ajax("Customer/Create", {

        type: "post",

        contentType: "application/json",

        data: {  }, // JSON data goes here

        dataType: "json",

        headers: {

            'RequestVerificationToken': '@TokenHeaderValue()'

        }

    });

</script>
 
If you are passing it in the header then you can use the below custom antiforginary validator attribute, so that you will get more control over the process. 
 

namespace Web.UI.Security

{

    using System;

    using System.Configuration;

    using System.Web.Helpers;

    using System.Web.Mvc;

 

    /// <summary>

    /// This method will validate anti forgery token in ajax requests,

    /// we must include the token in header to get it validated correctly

    /// </summary>

    /// <seealso cref="System.Web.Mvc.FilterAttribute" />

    /// <seealso cref="System.Web.Mvc.IAuthorizationFilter" />

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]

    public class ValidateAjaxAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter

    {

        public void OnAuthorization(AuthorizationContext filterContext)

        {

            if (filterContext == null)

            {

                throw new ArgumentNullException("filterContext");

            }

 

            var httpContext = filterContext.HttpContext;

            var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];

                //vaiadating the requst verification token in the request header

                AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]);

        }

    }

}

 

 

 

 

 


Friday 6 December 2019

Host two websites under same domain, which has different versions of Entity Framework package installed

We do have two websites which we need to host it under a same domain name , So for this we normally create a website and inside that we will be creating a new application for the child



This is not a big deal , but if we have packages with different versions installed in the websites then we will be getting a version conflict error. 

Example in our OLDProject we do have EF version 4x and NewProject has EF version 6x 
Then we will be getting an exception like 

Since we have an EF section in the OLDProject we dont need to add the EF section in NewProject 

What we need to do is remove the EF section from NewProject(Child) Then add a Assembly Redirect 

Comment below line ( Version may differ in your case 
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
Then Add an assembly redirect like below 
<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="6.0.0.0" />
      </dependentAssembly>
       </assemblyBinding>
 </runtime>

Thursday 5 December 2019

How to to use IHostingEnvironment in .net core class library?

Normally IHostingEnvironment will not be available in the class library. But its available in the Nuget as a package .

IHostingEnvironment  is part of Microsoft.AspNetCore.Hosting.Abstractions.dll

Install IHostingEnvironment  from Nuget package

Install-Package Microsoft.AspNetCore.Hosting

Then we are free to use the IHostingEnvironment  in class libraries also.


Warning
This API is now obsolete.
This type is obsolete and will be removed in a future version. The recommended alternative is Microsoft.AspNetCore.Hosting.IWebHostEnvironment.

Monday 2 December 2019

Configure Swagger UI in Web API


Swagger UI

Swagger is the largest framework for designing APIs using a common language and enabling the development across the whole API lifecycle, including documentation, design, testing, and deployment.
The framework provides a set of tools that help programmers generate client or server code and install self-generated documentation for web services.
However, there are many other frameworks like RAML, API Blueprint, Summation, etc. So, how to explain the huge popularity of Swagger? The answer is that it offers a lot of advantages and besides creating clear documentation provides other great things.
Swagger -Advantages


Ø  Swagger uses a common language that everyone can understand, it’s easily comprehensible for both developers and non-developers.
Ø  Swagger is easily adjustable, it can be successfully used for API testing and bug fixing

Ø  Swagger provides a set of great tools for designing APIs and improving the work with web services:

Ø  Generate Beautiful and Interactive Documentation

             Publish and Market your API



Different swagger tools

Ø    Swagger Editor – enables to write API documentation, design and describe new APIs, and edit the existing ones. The first open-source editor visually renders OAS/Swagger definition with error handling and real-time feedback.
Ø    Swagger Codegen – allows developers to generate client library code for different platforms. As the tool helps facilitate the dev process by generating server stubs and client SDKs, software engineers get the ability to faster build your API and better focus on its adoption.
Ø   Swagger UI – allows engineers to get self-generated documentation for different platforms. Swagger UI is a fully customizable tool that can be hosted in any environment. A great plus is that it enables developers to save a lot of time for API documentation.
Ø   Swagger Inspector – a tool for testing and auto-generating OpenAPI documentation for any API. Swagger Inspector allows to easily validate and test APIs with no limits on what you test. Tests are automatically saved in the cloud with a simple access.


Swagger UI Configuration:


Step 1: Create a web api project (Preferably you can opt template provided by Microsoft-scaffolding).



Step 2: Add swagger from Nuget package



Step 3: Check your solution you can see a SwaggerConfig.cs file inside App_Start folder.




Step 4: Open the SwaggerConfig file and uncomment below line

c.IncludeXmlComments(GetXmlCommentsPath());

Step 5: Include the method GetXmlCommentsPath in the file
 
private static string GetXmlCommentsPath()
        {
            return String.Format(@"{0}\App_Data/XmlDocument.xml", System.AppDomain.CurrentDomain.BaseDirectory);
        }

Note: There any many configuration changes you can do with swagger config look into the commented lines or swagger config or visit https://swagger.io/ for better understanding.

Step 6: Enable summary comments for the project



Uncomment below line from Areas->App_Start->HelpPageConfig.cs

config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));

Step 7: Add the summary comment xml file path in the project properties



Note: If you are using a project without scaffolding template, or if you need more idea on the help page summary comments then visit

https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/creating-api-help-pages

Step 8: Add a link for swagger UI







Step 9: Run your project and click on the Swagger link you can see the swagger UI

Note: If you want to enable custom headers are authentication headers in the Swagger UI then you create a filter like below for doing the same
public class AddAuthorizationHeaderParameterOperationFilter : IOperationFilter
    {
        public void Apply(Swashbuckle.Swagger.Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            if (operation.parameters != null)
            {
                operation.parameters.Add(new Parameter
                {
                    name = "Authorization",
                    @in = "header",
                    description = "access token",
                    required = false,
                    type = "string"
                });
                operation.parameters.Add(new Parameter
                {
                    name = "currentLanguage",
                    @in = "header",
                    description = "Current language",
                    required = false,
                    type = "string"
                });
            }
        }
    }

You can check the JWT reusable component (The one available in the reusable component factory) for working demo