Broken authentication
Preventing brute force (and more)
Select your ecosystem
What is broken authentication?
Broken authentication refers to vulnerabilities in API authentication mechanisms that allow attackers to impersonate users, access sensitive information, or perform actions as another user. This can stem from improper validation, weak credential management, or lack of security controls such as rate limiting or multi-factor authentication (MFA). Examples include APIs that allow brute-force attacks, use weak token validation, or do not enforce password policies.
About this lesson
In this lesson, you will learn how broken authentication can compromise an API's security. You will explore how attackers exploit these vulnerabilities, understand the technical causes, and implement effective mitigation strategies to secure your APIs.
Broken authentication in action
Meet Eva, a software engineer at an e-commerce company. She is testing an API that handles user logins. During testing, she discovers that the API allows unlimited password attempts without account lockout or rate limiting. Let's take a look!
Let's break down the bash script above
Eva’s findings revealed several critical vulnerabilities within the API, with the lack of rate limiting being a major issue. However, the investigation also uncovered other significant flaws that could compromise the system’s security.
Weak token validation
The API demonstrated weak token validation by accepting expired or unsigned JWTs. This flaw exposes the system to the risk of session hijacking, where attackers can impersonate legitimate users and gain unauthorized access to sensitive data or operations.
Unencrypted password transmission
Passwords were being transmitted over plaintext HTTP instead of the secure HTTPS protocol. This practice leaves user credentials vulnerable to interception by malicious actors who can exploit unencrypted network traffic to steal sensitive information.
Missing multi-factor authentication
Critical operations, such as password resets, lacked the implementation of multi-factor authentication (MFA). Without an additional verification step, the system fails to confirm the user’s identity, making it easier for attackers to compromise user accounts.
Predictable session tokens
The API used sequential or easily guessable session identifiers. This predictability allows attackers to manipulate or guess session tokens, facilitating session hijacking and unauthorized access to user accounts.
Each of these vulnerabilities stems from a failure to implement robust authentication mechanisms and to adhere to security best practices, leaving the API open to exploitation.
Vulnerable code example
Here is an example of what the vulnerable backend code may have looked like when Eva was able to send unlimited requests. This example lacks rate limiting functionality.
Here is a Python example of a login endpoint that handles user authentication. Although it processes requests effectively, the absence of proper security measures leaves the system open to exploitation.
In this Python code, the login function is mapped to the /api/login
route. The user’s credentials are extracted using request.get_json()
, and the find_user function retrieves the user’s data. If the stored password matches the password field in the request data, the generate_token(user)
function generates a token that is sent back as a JSON response. Failed attempts result in a "401 Unauthorized" response with the message "Invalid credentials."
The vulnerability lies in the unrestricted access to the login function. The find_user
call is unprotected against repeated requests from the same client or IP. An attacker can brute-force the password field without facing rate limits, delays, or account lockouts, enabling them to exploit the system until valid credentials are discovered.
What is the impact of broken authentication?
Broken authentication vulnerabilities can lead to severe and far-reaching consequences for organizations and their users. When authentication mechanisms are compromised, attackers can bypass security controls and gain unauthorized system access, leading to multiple serious impacts.
Account takeover (ATO) represents one of the most severe consequences. Once attackers successfully exploit weak authentication, they gain complete control over user accounts. This allows them to modify account settings, make unauthorized purchases, and change credentials at will. High-privilege accounts like administrators are particularly attractive targets, as compromising these accounts enables attackers to cause maximum damage. Compromised accounts are also frequently used as launching points for internal attacks or sophisticated phishing campaigns targeting other users.
Data breaches often follow successful authentication attacks. Attackers can access sensitive personal information, potentially exposing everything from basic contact details to complete identity information. Financial data, including credit card numbers and banking details, becomes vulnerable to theft.
Service disruption represents another critical impact of broken authentication. Large-scale attacks can overwhelm authentication systems with countless login attempts. This abuse of system resources consumes excessive bandwidth and processing power, potentially bringing services to a halt. Legitimate users often find themselves locked out of their accounts during attack mitigation.
Because of these severe consequences, organizations must implement robust authentication controls. Multi-factor authentication, rate limiting, and well-designed account lockout policies serve as critical security measures to prevent these attacks and their devastating impacts.
How do you mitigate broken authentication?
Enforce Strong Password Policies
Passwords should adhere to complexity requirements, such as including uppercase and lowercase letters, numbers, and special characters. Additionally, password validation should be implemented to ensure users are not using common patterns or compromised passwords. This minimizes the risk of brute-force attacks or credential stuffing.
Implement Rate Limiting
Rate limiting is essential to restrict the number of login attempts allowed per account or IP address. By setting a limit on repeated requests within a specified time frame, you can significantly reduce the likelihood of brute-force attacks. For added security, consider temporarily locking accounts after a certain number of failed login attempts or using CAPTCHA challenges to identify legitimate users.
Use Secure Token Practices
Tokens are a critical part of modern authentication, but they must be managed securely. Always validate tokens for expiration to prevent the reuse of outdated credentials. Additionally, ensure the token signature is valid and that audience claims align with the expected application context. These practices help prevent unauthorized access using stolen or manipulated tokens.
Require Re-authentication for Sensitive Actions
For particularly sensitive actions, such as password resets or email changes, require users to re-authenticate themselves. This ensures that even if a session is compromised, an attacker cannot make critical changes without additional verification. This step protects the integrity of user accounts and prevents unauthorized modifications.
Enable Multi-Factor authentication (MFA)
Multi-factor authentication (MFA) provides an extra layer of security by requiring users to present two or more verification factors, such as a password and a one-time code. Enabling MFA for all users significantly enhances account protection, even if passwords are stolen or compromised. This additional safeguard makes unauthorized access much harder to achieve.
Mitigated code
Below you will find some mitigated code. It's best to use a reputable third party to implement rate limiting, but similar logic will apply:
The Python implementation utilizes the Flask-Limiter library to enforce rate limiting. The @limiter.limit("5 per minute")
decorator restricts each IP address to five login attempts per minute, automatically managing throttling and tracking without requiring custom logic. authentication proceeds only if the user’s credentials match those stored in the system.
By using Flask-Limiter
, this code makes brute-force attacks infeasible because repeated login attempts from the same IP address are blocked. This eliminates the unrestricted access seen in the vulnerable implementation, providing robust protection with minimal additional code.
Test your knowledge!
Keep learning
Learn more about broken authentication with these resources:
- OWASP authentication cheatsheet: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
- Snyk API Security Guide
- Snyk How to Secure a REST API
- OWASP Top 10 API #2 broken authentication: https://owasp.org/API-Security/editions/2023/en/0xa2-broken-authentication/