API Extra Security Layer with Input Checksum using Laravel

A Checksum is a value used to verify the integrity of a file or a data transfer. So basically, it’s the digital fingerprint of each request.

How its work?

The sender send a request including the checksum and the receiver will reconstruct their own checksum based on sender inputs. Then, the receiver will compare it own checksum with sender’s checksum whether match or not. If not matched, the sender request consider invalid.

Image for post
Image for post

So i came out just simple solution using Middleware to validate request checksum.

Basically, what i plan to do is the client-side will construct a MD5 checksum based on input and put it in HTTP header. Then, server-side will check if http header exist and validate it.

Client Side

  1. Sort every input value based on key in alphabetical order and make it inline with delimiter. For example, =>
  2. Put the checksum in custom HTTP header (X-Checksum) and send to the server.

Server Side

  1. Construct checksum using the same way as client side do.
  2. Compare server checksum with request checksum.

Why MD5? It’s the simplest way to show how actually to do checksum 😁. You are freely to replace it with any Hashing(MD5, SHA..), Asymmetric (RSA..) or Symmetric (AES..) encryption method.

First, we create a middleware first. Let’s call it

class ChecksumValidationMiddleware {}

Specify constant header

Define constant what would be the HTTP header name should be send by API

const CHECKSUM_HEADER = 'X-Checksum';
const DELIMITER = '|';

Reconstruct request and validate checksum

Let’s use collection. Sort all the keys in ascending order and merge using delimiter

public function handle(Request $request, Closure $next)
{
$checksum = md5(
collect($request->all())
->sortKeys()
->join(self::DELIMITER)
);

if ($checksum != $request->header(self::CHECKSUM_HEADER)) {
throw new SecurityGlobalHeaderException("Invalid Checksum");
}

return $next($request);
}

It’s very straight forward actually.

How about we combine with Timestamp validation? it will be something like this

Conclusion

I recommend you to use asymmetric cryptography to create a checksum. Client will create checksum using public key and Server side will compare it using private key. It’s much more secure actually.

That’s it. A simple checksum in Laravel. Hope its help 😁

Thanks for your time.

I’m an Software Engineer with a demonstrated history of working on Full-stack with Android, Vue and Laravel Framework

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store