Lack of Protection Against Brute Force Attacks
Need
Prevent automated attacks designed to guess credentials
Context
- Usage of Elixir (v1.10+) for building scalable and fault-tolerant applications
- Usage of Plug for request handling
- Usage of Phoenix framework for building web applications
Description
Non compliant code
def handle_post(%{params: %{"username" => username, "password" => password}} = conn, _opts) do
if Users.validate_credentials(username, password) do
conn |> send_resp(200, "Logged in!")
else
conn |> send_resp(401, "Invalid credentials")
end
end
This code is vulnerable because it does not implement any control mechanism against brute force attacks. It simply checks if the credentials are valid and responds accordingly. This allows an attacker to try different combinations of usernames and passwords until they find a match.
Steps
- Integrate a rate limiting mechanism in your application to limit the number of login attempts from the same IP address or for the same username in a certain period.
- Use a CAPTCHA system to prevent automated scripts from making login attempts.
- Implement account lockout policy after a certain number of failed login attempts.
Compliant code
def handle_post(%{params: %{"username" => username, "password" => password}} = conn, _opts) do
if RateLimiter.allow_request(username) and Captcha.verify(conn.params["captcha"]) and Users.validate_credentials(username, password) do
conn |> send_resp(200, "Logged in!")
else
conn |> send_resp(401, "Invalid credentials or too many attempts")
end
end
defmodule RateLimiter do
def allow_request(username) do
# Rate limiting logic here
end
end
defmodule Captcha do
def verify(captcha_response) do
# Captcha verification logic here
end
end
The secure code integrates a rate limiting mechanism using the RateLimiter module, which limits the number of login attempts for the same username. It also includes a CAPTCHA system using the Captcha module. If either the rate limit has been reached or the CAPTCHA verification fails, the user is not allowed to attempt to log in.