logo

Lack of protection against brute force attacks - Ruby


Need

Implementation of strong and effective protection against brute force attacks


Context

  1. Usage of Ruby for building web applications and scripting
  2. Usage of Ruby on Rails for building web applications

Description

Insecure Code Example

class SessionsController < ApplicationController
  def create
    user = User.find_by_email(params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to root_url, notice: "Logged in!"
    else
      flash.now.alert = "Email or password is invalid"
      render "new"
    end
  end
end

The above code is a simple implementation of an authentication system in a Ruby on Rails application. The `create` method in the `SessionsController` is responsible for logging in a user. When a POST request is made to the `/sessions` endpoint (which calls the `create` method), the application tries to find a user with the provided email. If a user with that email exists, it then checks if the provided password matches the password of the found user. If the password is correct, the user is logged in and redirected to the homepage. If the email or password is incorrect, an error message is displayed. However, this code is vulnerable to brute force attacks. There are no protections in place to limit the number of login attempts. This means that an attacker could use an automated script to repeatedly try different combinations of emails and passwords until they find a combination that works. This is a serious security risk as it could potentially allow an attacker to gain unauthorized access to user accounts.

Steps

  1. Implement account lockout mechanism after a certain number of failed login attempts.
  2. Use strong and unique passwords for user accounts.
  3. Implement CAPTCHA or reCAPTCHA to prevent automated login attempts.
  4. Implement rate limiting to restrict the number of login attempts within a specific time period.
  5. Implement two-factor authentication to add an extra layer of security.
  6. Regularly monitor and analyze login logs for any suspicious activity.
  7. Educate users about the importance of using strong passwords and avoiding password reuse.
  8. Implement session expiration and automatic logout after a certain period of inactivity.
  9. Regularly update and patch the application and its dependencies to fix any security vulnerabilities.

Secure Code Example

class SessionsController < ApplicationController
  MAX_LOGIN_ATTEMPTS = 5

  def create
    user = User.find_by_email(params[:email])

    if user && user.failed_attempts < MAX_LOGIN_ATTEMPTS
      if user.authenticate(params[:password])
        user.update(failed_attempts: 0)
        session[:user_id] = user.id
        redirect_to root_url, notice: "Logged in!"
      else
        user.increment!(:failed_attempts)
        flash.now.alert = "Email or password is invalid"
        render "new"
      end
    else
      flash.now.alert = "Your account has been locked due to too many failed login attempts"
      render "new"
    end
  end
end

The updated code now includes a mechanism to lockout a user account after a certain number of failed login attempts. This is done by adding a `failed_attempts` field to the User model, which keeps track of the number of consecutive failed login attempts. When a user tries to log in, the system first checks if the user exists and if the number of failed attempts is less than the maximum allowed. If the user exists and the number of failed attempts is less than the maximum, the system then checks if the provided password is correct. If the password is correct, the `failed_attempts` field is reset to 0 and the user is logged in. If the password is incorrect, the `failed_attempts` field is incremented by 1 and the user is not logged in. If the number of failed attempts is equal to or greater than the maximum allowed, the user is not allowed to log in and a message is displayed indicating that the account has been locked due to too many failed login attempts. This mechanism helps to protect the system against brute force attacks by limiting the number of login attempts a user can make within a certain period of time.


References

  • 053 - Lack of protection against brute force attacks

  • Last updated

    2023/09/18