DEV Community

Ravi Ranjan Pandey
Ravi Ranjan Pandey

Posted on

1

How to securely send/receive key params in an .NET Core WebAPI and Javascript Application

In an api its common to have some identifier keys to identify user details and process data accordingly. Its also common to take these details from either query parameters or headers or route path from client side.
However these apis will be rejected in the security audit process as they expose user data and has insecure object reference vulnerability, which can be maliciously exploited to get information of other users by tweaking these api parameters.
There are many ways to handle this security issue, however in this tutorial i will explain how to handle this by encrypting these params together into a single key and sending that in a header. I will also explain how to handle it at the api level using a middleware in .NET Core Api. Encryption is done in javascript to use in a client application and decryption is done in C# at the API level.
I have used AES Key-Based Encryption algorithm to achieve encryption and decryption.

Lets assume we have an salaries api with employeeid as param

api/salaries/getbyemployeeid?employeeid=1031

in this api, we are exposing an important key identifier employeeid and hence its exposed because anyone with some basic authentication can check details of another employee to avoid this first we will remove the query parameter.

api/salaries/getbyemployeeid

next we will generate an encrypted key using AES Encryption and then we will send that key as header.

Encryption in JavaScript

install the package npm install crypto-js


const CryptoJS = require('crypto-js');
function Encrypt(str) {
                 var KEY = "12345678900000001234567890000000";//32 bit
                 var IV = "1234567890000000";//16 bits
        var key = CryptoJS.enc.Utf8.parse(KEY);
        var iv = CryptoJS.enc.Utf8.parse(IV);

        var encrypted = '';

        var srcs = CryptoJS.enc.Utf8.parse(str);
        encrypted = CryptoJS.AES.encrypt(srcs, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });

        return encrypted.ciphertext.toString();
    }
var encryptedEmployeeId = Encrypt("1031");
console.log(encryptedEmployeeId);
//result would be EF082204BF6F804099396A96CC7733F4

Enter fullscreen mode Exit fullscreen mode

Decryption in C#


public class EncryptDecrypt
{
    public static string AESDecryption(string input)
    {
        string AES_IV = "1234567890000000";//16 bits 
        string key = "12345678900000001234567890000000"; //32 bits
        byte[] inputBytes = HexStringToByteArray(input);
            byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 32));
            using AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider();
            aesAlg.Key = keyBytes;
            aesAlg.IV = Encoding.UTF8.GetBytes(AES_IV.Substring(0, 16));

            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
            using MemoryStream msEncrypt = new MemoryStream(inputBytes);
            using CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read);
            using StreamReader srEncrypt = new StreamReader(csEncrypt);
            return srEncrypt.ReadToEnd();
    }

private static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            return buffer;
        }
}

Enter fullscreen mode Exit fullscreen mode

Send encrypted param in the header
I added a header named Request-Id
Request-Id : EF082204BF6F804099396A96CC7733F4

Adding a Request Middleware to grab the header value and Decrypt it.


public class RequestMiddleware
    {
        private readonly RequestDelegate _next;
        public RequestMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Headers.TryGetValue("Request-Id", out var requestid))
            {
                var employeeid = EncryptDecrypt.AESDecryption(requestid);     
            }

            await _next(context);
        }
    }

Enter fullscreen mode Exit fullscreen mode

Configure the Middleware before the middleware used for other apis to make it available and can be saved in a static variable.

app.UseMiddleware(typeof(RequestMiddleware));

Conclusion
So, in this tutorial i explained how can we send key based encrypted parameter in an api request in the header instead of sending directly and modified the api as shown initially.

SurveyJS custom survey software

JavaScript UI Library for Surveys and Forms

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

View demo

Top comments (0)

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay