Prevent Brute Force Attacks in Node.JS

Poorshad Shaddel
Level Up Coding
Published in
5 min readMar 20, 2022

--

Brute Force Attack

What is a Brute Force Attack?

When you have an application that needs user authentication then someone can try all possible combination of letters, numbers and symbols and send them one by one to find out a specific user’s password. This is a brute force attack in simple words.

What is Dictionary Attack or Hybrid Brute Force Attack?

Usually trying all possible combinations of letters, numbers, symbols is not a fast way to get a user’s password. In order to increase the speed, attackers usually use dictionary words, most of the time people choose a password to recall easily and as a result most passwords are combination of valid words and simple numbers. Also there are some common password databases that attackers use as a dictionary.

In order to feel the problem let’s talk with some useful data from cyber news that extracted from breach compilation.

Top 10 most common passwords:

123456
123456789
qwerty
password
12345
qwerty123
1q2w3e
12345678
111111
1234567890

Most popular years used in passwords:

most popular years used in passwords

Where can I find password dictionaries for testing purposes?

In this website, you can find a list of dictionaries.

Different scenarios of the brute force attacking and the way we can prevent

1. Brute Forcing one specific user from one IP

In this scenario, the attacker is trying possible passwords on a specific user from only one specific IP. Preventing this kind of brute force is easy. We can simply prevent this by having a rate limiter based on IP:

If you are using express there are a variety of packages to do this, one of them is express-rate-limit

express rate limit

As we can see in limiter configuration each IP can send only 5 per 10 minutes.

It is still not perfect, we are going to improve this in the next steps.

2. Brute Forcing one specific user from different IPs

In this scenario, the attacker has lots of zombies and he is trying to brute force the user’s password by sending requests from these zombies, or the attacker has access to different proxies so we cannot recognize this brute force by just focusing on IP.

The solution is having a limited number of login attempts. Let’s implement the simplest way we can store these login attempts and act based on the situation and after this, we are going to see a fancy package.

The logic is super simple, if a user is failed to login we are going to store a key in Redis and each time user is trying to login and it fails I increment this number. If this number is bigger than ‘maxNumberOfFailedLogins’ I do not let users try to login. Also each time I set the expiration time of Redis key to 1hour, so if the attacker wants to send a login request again he/she should wait for one hour.

Another thoughtful way is to prevent users from login attempts with dynamic duration, in this way even bots are in trouble but it might get on your users’ nerves too.

Sending an email to the user or disabling the account is another good choice based on your application and business.

The implementation we saw was simple and definitely it has some flaws so a better way of handling this is using node rate limiter flexible.

3. Wide scale brute force attacks

This method is trying to bypass account lock-out. With this method, the attacker is sending requests from zombies and attempting different users and passwords.

Sending requests by Zombies

What could happen to your application? If your app is under attack frequently several hundred user accounts could be locked-out or not being able to login.

This is a kind of denial of service since the probability of finding a user’s password is not high(They have neither the username nor password). We can try DDoS prevent techniques.

Another efficient way to prevent these requests is having a Captcha.

Are you a robot? :)

By having a captcha you are preventing these login attempts and as a result, your users are able to login and react with your service normally even during the attack.

Check out this article if you want to implement google captcha on Nodejs.

Other ways to make the brute force attacker’s life harder

Require use of strong password

Force users to use numbers, symbols, capital letters and prevent users form using more 2 or 3 sequential numbers or characters in their password.

check-password-strength package can help you.

check password strength

Use Two Factor Authentication

by sending a code in email or a text message beside the password you can make it really difficult to get access to user’s account. Even if you are not doing this for all users you should consider two factor authentication for users with special privileges.

Different Login Urls

This is not a fancy way to prevent brute force attacks but most of automated tools are not designed to handle this design. In Nodejs you can easily implement this:

Use allowed IP address for advanced users

Let advanced users who have special access set some allowed IPs and only let them login from those specific IPs.

Detect unknown browsers and devices by using cookies

Prevent users from trying to login from unknown devices and browsers, or like Google let them know that someone is trying to login from an unknown device. You can capture device info with express device capture.

Not giving extra information on failed login

If a login attempt fails do not let them know if the user exists or not. Most websites tell you that Password Or User is Incorrect.

If you let the attacker know that the user exists or not then they can gather a list of your users for further attacks.

Summary of Actions to Prevent Brute Force Attack to your app

  • Limited failed login attempts
  • Limit logins from specified IP address
  • Two Factor Authentication
  • Strong Passwords
  • Captcha
  • Different Login URLs
  • Use Allowed IPs for special users
  • Detect login attempts from unknown browsers and devices
  • Not giving extra information on failed login

--

--

Full Stack Developer with more than 6 years of expericence. I spend partial part of the day working with Node.js and React.