Guide to a more Secure Login System
Every website has a login register system (or simply login system). The simple reason is due to the access to more customized data that can be viewed from two different perspectives. Macro and micro, one focusing on trends, analytics, usage and a 51 percent approach. On the other hand, a micro focused approach enables any service to better cater needs of each user. The merits of these approaches have consequences and benefits that are better left to a discussion of its own hence, i digress.
I want to more specifically focus on the idea of a secure login registration system now that one has a bird’s eye view of the idea such a service can provide be it in a service such as Amazon Shopping or just plain old Netflix. Even keyboard optimisation is something of a service that can be provided by just creating a user. Let’s not beat around the bush now and rather focus on the subject at hand now.
An login system has two surface level processes
- Registration — While, registration is simply taking in relevant data and storing it for authenticating and providing better usage patterns to a user.
- Login — Login is simply using the already stored data and verifying if said data is true.
With the basics out of the way, Let’s consider NodeJS as the framework in question being used to develop the app. Then, here’s a simple system design diagram of how the system should be working.
Here, is one concept that we usually skip which is Hashing (Reffering to the step, password is hashed). Hashing is essentially encrypting the password in a a form that makes no sense to anyone but the hashing algorithm.
The Hashing Algorithm
This is a term that is thrown around quite a bit however, here is a better explanation so as to what it actually is.
Hashing simply means taking the password and converting it into a long string of alphanumeric code using a one-way function. Meaning, the encryption is one way.
On thinking a bit, one can observe two gaping holes in this solution.
1. Length of the password varies.
2. Passwords aren’t unique.
The solution to both these issues is a predetermined string called SALT and this makes a hashing algorithm very secure.
The idea here, is to add a string unique to each user to the password and then hash it. This makes the length of the password equal (or in a specified range)and also, unique to everyone.
This length is increased to make a brute force dictionary or password guessing attack harder. A specified range makes even SQL injection ineffective since the function is already one-way.
Common Issues
Eagle eyed developers and potential system designers might want to reduce their API calls by hashing the password on the frontend and then sending it to the backend server. Furthermore, a similar principle can be applied to the login process by hashing it while still in frontend and then sending it.
This has major issues since, a hash attack can be easily implemented by a hacker wherein the hashed password is directly sent for validation to the server and a status code of 200 OK is recieved. Thus, they gain access to the account. Therefore, it better to utilise a backend middleware function for hashing with a library such as bcrypt or scrypt if working with NodeJS.
Also, using tokens to prevent csrf attacks is good idea. JWT is a good library to implement the said feature.
What risks arise if SALT is not used?
Earlier on, I mentioned SALT an alphanumeric string added to the passowrd but one might decide not to do it. Due to the added time that is taken up for creating and encrypting the said hashed password + SALT = key
Even, though hashing algorithms such as MD5, SHA1, SHA2 family algorithms are one way. One can use a rainbow table wherein, common passwords used across the internet are stored in their hashed form. And thus, cracking gets easier.
However, since every salt is unique for every user a rainbow table attack becomes irrelevant. and hackers have to rely on the classic dictionary attacks or password guessing. One way to thwart even this is IP tracking or location tracking. If the IP or location of the device accessing is different one can ask for a forced two factor authentication. Or simply use QR codes for login.
Some other tips
Some other mistakes would be
Incorrectly configuring the UFW on a linux server which includes keeping unnecessary ports such as 8000 open.
Use HTTPS by obtaining a SSL certificate.
Use SSH key pair authentication to access your server instead of a password.
Wrongly configuring the CI/CD pipeline on the side of your code repository (e,g GitHub), etc.
Thanks for reading!