DEV Community

Poorshad Shaddel
Poorshad Shaddel

Posted on • Originally published at levelup.gitconnected.com on

Why Implementing Your Own Username Password Authentication System Could Be a Big Mistake!

This is an awareness about the dangers of implementing your authentication system!

Why I wrote this article?

In almost all the projects and companies that I have worked with, we had our own Username Password authentication system, as a result, we have faced a lot of challenges and this article is a summary of the challenges we had and what to consider before jumping into it.

Some of the reasons I think using our own Username-Password authentication could be a mistake:

  • Cybernews analyzed 15 billion passwords and found that nearly 30 percent of them featured just 8 characters , 20 percent had just 6 characters!
  • “123456” is still the most popular password (NordPass)
  • Nearly 6 in 10 Americans have used personal information such as their name or birth date in passwords (Google)
  • 52% of internet users admit to resetting passwords regularly (ExpressVPN)
  • Weak passwords are the root cause of 81% of all data breaches (Verizon)
  • Just 45% of US consumers change their passwords after a data breach (Google)
  • Hackers leaked over 721 million passwords in 2022

Another super important factor in my opinion is the massive amount of time that we need for implementing a good quality authentication system. An authentication System is not something that you can deliver without a high test coverage, and that needs a lot of effort. In the next section we will see which features are needed for a authentication system and what to consider in implementation.

Picture of a Login page and a man and woman beside it

Authentication Features and Challenges

Choosing a Hash Function

Some of the hash functions are considered weak, this is a small list:

MD5, SHA-1, RIPEMD & RIPEMD-128 , Whirlpool

But probably this is not a big issue, since there are some other strong hash algorithms like Argon2id, bcrypt, scrypt.

Secure Storing of Secret

For hashing the password you probably need a secret. Keeping this secret secure is also really important. To avoid having this secret in your code, if you are using Kubernetes, you can use K8s Secrets.

Login with Email

If you want to allow users to Login with their email, you already need a new implementation for verification of email. You already need a mail service even before starting your project! This verification could be done by sending a code, or a link that results in verification and a valid user session. Testing this is doable by mocking the mail service.

Login with Email

Duplicated Emails

It is easy to implement but the problem is that you are giving the anonymous request sender some information about existing users emails! So as a result you have to use something like a rate limiter to avoid someone making a list of your application user emails by brute force.(preventing username or email enumeration attack)

Login or Register with Phone

You need an SMS service to verify that the user owns the number. If you are allowing register with a phone number, also here you should be careful about Enumeration attacks, the attacker can get some existing phone numbers and try to target those users with social engineering or phishing attacks.

Password Policy

Choosing the standard password policy is also important, For example:

  • Not less than 8 Characters
  • Up to 64 Characters
  • Allow usage of all characters including unicode and whitespace. There should be no password composition rules limiting the type of characters permitted.
  • Include a password strength meter to show the user how strong is their password!

zxcvbn-ts is a nice package for showing the strength of the password to the user.

This is the most basic functionality of an Authentication System. the User should be able to log in with a username or password!

Enter the Password

Reset Password

We usually send a reset password link or a code to allow the reset password process. What to consider?

  • Sending consistent message(not email not found!)
  • Response time in cases that the email does not exist!
  • Tokens should be safe, single use and expriable!
  • Use a Rate Limiter for avoiding Bruteforce

Locking Account on Multiple Try

This is a logic quite similar to cell phones, if you enter the wrong pin a few times, you have to wait for a while to be able to try it again. In order to avoid brute force on specific accounts, you have to lock the account when someone is sending a lot of wrong passwords to that specific user. Implementing this logic requires also a policy for unlocking the account. For some use cases, they unlock the user after a period of time. For some other use cases only support users are able to unlock these users.

Session Management

Google Showing List of Your Active Sessions
Google Showing List of Your Active Sessions

Session manager might also be something specific to Finance sector, but I had to implement it twice! But honestly this is not a complicated feature to implement, it just adds a bit of complexity and a bunch of code and more tests to your codebase.

Risk-Based Authentication (RBA)

You see an email once in a while, when you try to Login from a new Browser or device in your Google Account. This restriction might be neccessary if you are working in finance sector. You need tell the user that there was a suspicious activity. Another result of this feature is that you need to store IP Address(or a Hash of it) somewhere to check each Login against this list of IP Addresses.

Persisting Sessions

This is also a question that you should answer usually the moment you want to implement your own authentication system. Nowdays everyone is using containers and deploy their applications on K8s or Serverless, as a result you do not have a monolith and you might have more than once instance of the application, so you cannot use memory as a store for your sessions. Usually it is recommend to use a key-value store, because Databases are slow(I doubt this one! Databases are not slow specially if you have the correct index, they might not be as fast as key-value stores but they are definitely not slow!). So you need something like Redis.

Security Concerns

These are only some of the security concerns and attacks which you should be familir with before thinking about your own authentication system.

BruteForce Attacks

For fighting bruteforce attacks, having a complex rate limiter is vital. The user should not try a lot of username at registration, otherwise it can make a list of users and later target this group. User should not be able to send a lot of password reset emails at once. My favorite package on Nodejs is this node-rate-limiter-flexible that supports complicated cases.

If you are intereseted in checking out the details of BruteForce Attack you can check this article from me:

Prevent Brute Force Attacks in Node.JS

Username Enumeration

The username enumeration is an activity in which an attacker tries to retrieve valid usernames from a web application. The web applications are mostly vulnerable to this type of attack on login pages, registration form pages or password reset pages.

SQL/NoSQL Injection

You always have to validate data that comes from the user and frontend. Sanitizing is also vital in case of Login, Register and Reset Password. Sanitzing means that you are not letting the user to pass something like a regex that could do something you do not expect in your code(for example fetching all users instead of one).

How to Prevent No-SQL Injection in Node.js

CSRF Attack

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. For example the attacker could execute change email, change password. Usually we solve this issue by using a CSRF Token.

Prevent CSRF Attacks in Node.JS application

Session Fixation

The attacker has his own valid session and tries to associate it with another user. The problems occur when we are not generating new sessionIds(unique identifier) on actions like Login. Passportjs the most famous authentication library in nodejs had this vulneribility until version 0.5.0. Read the Passportjs maintainer article here.

I have also covered this issue on my medium

What is Session Fixation and How to Prevent it in Node.js

More Code, More Bugs!

I think this is not 100% true, the more accurate sentence will be “The More Code, The More Possibility of Bugs”. If we implement all of these logics in our code, even if we are aware of security concerns there is a good posibility that we see some bugs, in both category of security, and functionality. This is another reason why I wrote this article, all these logic could be handled by somthing like Google, Apple, Github or any third party authentication service and we can focus on our business logic.

More code = more bugs

Is there a Solution?

Definitely!, you can use Google Login, Apple Login, Github Login or Third Party Authentication Services like Keycloak, Auth0, AWS Cognito, FusionAuth and a lot of other options(both open source and closed source). By not implementing authentication yourself you are saving a lot of time and energy. My personal experience was that we could not ignore a good test coverage for authentication features and bugs, as a result we had to implement a lot of tests to be sure that everything is working as expected.

What if we loose some users because of not having the traditional username password?

This is a question that only your specific product and targeted users can correctly answer, but it is always a trade off, you might loose some users but you gain time and energy for building more business related features that might attract some more users.

Conclusion

Implementing our own authentication system could be a big security risk, and even for those who do not care that much about security(Do you really?), the cost of implementing all the features, tests and manual testing is really high. I think this is a mistake beacuse there are a lot of easier options which their main focus is this topic and the possiblity that they make mistakes is much less than us!

https://docs.xperience.io/spaces/flyingpdf/pdfpageexport.action?pageId=62069615


Top comments (0)