What is broken authentication? What makes a strong password? How can poor session management result in broken authentication? Read on to find out.
Data breach incidents have been on the rise for the past couple of years. According to the IBM 2022 report, the global cost of data breach has climbed to $4.35 mln while the USA takes the first place with the average data breach cost nearing $9.5 mln. Hackers keep using old ways and inventing new techniques to obtain sensitive consumer data.
One way to infiltrate a targeted system is to probe different authentication vulnerabilities. Broken authentication often depends on other attacks like social engineering, phishing, man-in-the-middle, or cross-site scripting.
In this article, we’ll explain what user behavior and developer’s mistakes lead to broken authentication and share effective strategies to prevent it.
What is Broken Authentication?
Before we dive into broken authentication, let’s first define authentication. In essence, authentication is verifying the user’s identity by requesting some private information known to this user only, such as their user ID, email and password, or a fingerprint scan.
Broken authentication is a web vulnerability that allows hackers either to bypass authentication controls, steal someone’s identity to log in, or break other security mechanisms. Broken authentication can be caused both by negligent credential management and poor session management.
Poor Credential Management Examples
Using someone else’s credentials is one of the most common ways for bad actors to access a system. In 2022, stolen credentials were the primary attack vector in 19% of breaches in the 2022 IBM study. And it’s not surprising.
First of all, lots of people use weak passwords, and we’re not talking about ‘123’, ‘admin’ pet names, and dates of birth, even though millions of users are still using these. And we’re not exaggerating – the data below speaks for itself.
On top of that, research shows that 44% of consumers change their password once in a blue moon. This means that hackers can launch brute-force and password-spraying attacks and steal credentials with little effort.
Brute-force attacks are automated and rely on a simple trial-and-error method. Password spraying is a type of brute-force attack. However, instead of trying numerous passwords on a single account, it uses the same password for multiple users. The latter allows hackers to bypass account lockouts after a certain number of failed login attempts.
Another group of people uses the same email and password across all their accounts. According to Statista, only 12% of users always created new passwords when registering new accounts in 2021, whereas 45% either always or mostly reused old passwords.
This gave rise to credential-stuffing attacks. The darknet is filled to the brim with leaked emails and passwords of different organizations. Because people use the same passwords for several apps, attackers can use credentials obtained from the darknet and try them for targeted sites. Credential stuffing is also an automated attack, which means it is a low-effort endeavor for hackers.
But users are not the only culprits here; there can be mistakes on the developers’ part too. For example, passwords may be stored in plain text or use weak hashes, which makes it easy for hackers to decrypt them with rainbow tables.
Why is Session Management Important?
Session management is an integral part of modern web apps. A web session is a sequence of network HTTP requests and responses pertaining to the same user. Web apps use sessions to retain information about a particular user to properly respond to all their actions and requests for the duration of the session.
For example, when a first-time user navigates the site, their language preferences will be saved throughout the entire session, which improves usability.
Sessions are equally useful in post-authentication scenarios too. Once the user has authenticated, the web app will be able to identify this user during subsequent interactions and apply respective security controls.
Once a session is created, the user is assigned a session ID or token temporarily equivalent to the strongest authentication method and exchanged by the user and the web app during the session.
Broken Authentication and Session Management Examples
Correct session implementation plays a tremendous role in preventing authentication vulnerabilities. Here are just a few examples of how improper session management leads to broken authentication.
Session Hijacking. It can take many forms. The simplest example of session hijacking is when a user fails to invalidate their session on a public computer: they may close just the browser windows without logging out from the apps. In this case, the person who takes the same computer afterwards could easily impersonate that user because the session is still active and the apps are unlocked.
But hackers don’t just go to public spaces trying their luck. Most of their attacks are planned beforehand and performed remotely. Another way to hijack a session is to eavesdrop on the network traffic using packet sniffers like Wireshark. If web apps use TLS encryption only on login pages, hackers can monitor the traffic on other pages and steal session cookies.
Bad actors could also try stealing the session token with cross-site scripting (XSS). Basically they craft a link with a special code that will be executed once clicked. The script can be written in JavaScript or any other client-side language. Here is an example of a malicious script that will reveal the cookie value in a pop-up:
<script>
alert(document.cookie);
</script>
Session Fixation. In a session fixation attack, the hacker connects to the web app to get a valid session ID and then tricks a legitimate user, whether through social engineering or a phishing site, to authenticate themselves with that session ID. This way, if the app doesn’t renew the session ID upon authentication, the hacker can impersonate the user and access their account.
Here is an example of a malicious link that will change the value of the victim’s session ID in their cookie if they click on it:
http://website.сom/<script>document.cookie=”sessionid=abcd”;</script>
Session ID URL rewriting. If a web app inserts the session ID into the URL instead of storing it in the cookie, it exposes it and allows anyone following the URL to inherit the session. So if such a URL is mistakenly shared, another user can take over the session without the need to authenticate.
Companies Affected by Broken Authentication
Let’s look at real-life examples of companies that suffered data breaches because of credential mismanagement or other authentication vulnerabilities.
Revolut is a money app for sending funds, requesting payments, and splitting bills in over 200 countries. In September 2022, Revolut suffered a data breach, exposing names, emails, phone numbers, postal addresses, device details, transaction history, and the last known IP addresses of about 50K users.
Even though the debit and credit card data was masked and unusable, the stolen information can be used for identity theft and phishing attacks. The breach investigators believe the database was compromised by an employee who fell victim to a meticulously crafted social engineering attack and handed login credentials to the hackers.
Twilio is a customer engagement platform that provides communication APIs for SMS, voice, and video channels. Twilio was breached in August 2022; hackers accessed data from 125 Twilio customers. Among the secondary victims of the breach were big names like Signal and Okta. Again, the attack was performed by tricking employees into following a phishing URL from SMS, allegedly to update expired passwords or see scheduling changes.
Twitter, one of the world’s largest social media networks, was also hacked in 2022. What happened is that their code update in June 2021 caused the following vulnerability: when hackers submitted an email or phone number to Twitter’s system, the site would reveal the Twitter account associated with that phone number or email. As a result, the personal data of 200 mln users was disclosed, which can lead to phishing fraud or identity theft in the future.
Crypto.com is a cryptocurrency exchange that lost about $30 mln in Bitcoin and Ethereum. Its two-factor authentication system turned out to be weak enough for hackers to bypass it. Hackers managed to withdraw funds from 483 customer accounts. The company intends to replace the two-factor authentication with a multifactor one to curb such incidents henceforward.
LastPass is a password manager that allows you to store and share passwords and other valuable documents. It was breached twice. The first time hackers stole part of the source code and some proprietary technical information through a compromised developer’s account. The second time they stole customer password vaults. While the latter are encrypted, hackers can brute-force the master passwords that lock the vaults.
How to Prevent Broken Authentication
The best way to prevent broken authentication is to implement a multi-layered security approach. Let’s go over essentials that will help you achieve it.
Add Multi-Factor Authentication
Multi-factor authentication (MFA) is an extra security layer that requires the user to present another piece of evidence to log in. It may be a PIN, a code sent to your phone or email, a fingerprint, face or iris scan, or a time-based one-time password (TOTP) from a respective authentication app.
Microsoft believes adding MFA would have stopped 99.9% of automated password-related attacks. However, MFA has several disadvantages: it decreases usability, adds external dependencies to the system, and offers no easy way to reset it without defeating its purpose.
As a way out, MFA can be implemented only for admins and users with high-privilege rights or for high-impact transactions only. The form in which MFA needs to be implemented depends on factors like the app’s threat model, the users’ tech savviness, the extent of administrative control over users, and overhead costs.
Add CAPTCHA
CAPTCHA is the abbreviation for the Completely Automated Public Turing Test to Tell Computers and Humans Apart. In layperson terms, it’s a quick check to distinguish humans from bots.
Original CAPTCHAs required the user to guess the distorted and overlapped characters and numbers and enter them into the input field. As bots become smarter at pattern recognition, there arose the need for more intricate image-based tests.
CAPTCHAs definitely add friction to the user journey, so it makes sense to use them only after a couple of failed login attempts.
While CAPTCHA makes brute-force attacks inconvenient and more expensive, it cannot ensure 100% protection against them.
Store Passwords Securely
By far, everyone has probably heard that passwords should never be stored in plain text because databases get compromised all the time. So even if a hacker gets their hands on the database, its contents will remain encoded.
Developers can achieve this with modern hashing algorithms. Hashing, unlike encryption, is a one-way function, so you cannot decrypt it, and that’s why passwords should be hashed rather than encrypted.
At the same time, there are still workarounds like calculating hashes for commonly used passwords and then comparing them with the hashes from the breached database. To make hackers’ job more difficult, password hashes should be salted, meaning a randomly generated string unique for every user will be added to the hashes.
Salted password hashes take significantly more time to crack and make it impossible to tell if two users have the same password because different salts result in different hashes, regardless of whether the users’ passwords are identical.
Enforce Strong Password Policies
What is considered a strong password? According to the National Institute of Standards and Technology, passwords should be at least 8 characters long and contain no repetitive or sequential characters (like aaaa or abc123). Additionally, users must be allowed to choose from all characters, including Unicode and whitespace.
But that’s the lowest threshold, and you don’t want to be at the rock bottom when it comes to security. The OWASP Application Security Verification Standard requires passwords to be at least 12 characters long, whereas developers of password strength meters like Bitwarden suggest 14 to 16 characters.
Generally, the longer the password, the better because it increases the number of combinations a botnet needs to crack. But keep in mind that the characters need to be randomly generated.
Some websites limit the number of characters you can use, so another way to add complexity to your password is by using capital letters, special characters and numbers. Again, randomness is a key factor when adding those. For example, “Logmein!321” is a terrible password pattern, whereas “l_w4XgH9~Wiq” is what we’re trying to achieve.
The login form should have a built-in password strength meter, checking passwords against dictionary words, previously breached passwords, or context-specific words like the service or user name and their derivatives.
When introducing password expiration policies, remember that employees tend to change just one character to get it over with and move on with their daily tasks. Therefore, it’s important to educate employees about what makes a strong password and request the password change only if there’s a suspicion of or an actual compromise. Because hackers don’t sit on exposed credentials, they act immediately.
Coming up with strong passwords for numerous services and storing them in a secure fashion is definitely an extra burden on employees’ shoulders. So, organizations need to provide a sanctioned method for generating and storing corporate passwords, whether a physical storage, password management software, or a combination of both, and clearly define employee actions in different scenarios.
Otherwise, employees will continue using weak, easily remembered passwords and improvise with storage, saving passwords on personal phones or Gmail drafts.
To prevent long password denial of service attacks, the maximum password length should be set, which is usually 64 characters.
- At least 14 characters long
- Add characters like ~@!&_?
- Place all characters randomly
- No pet names or birth dates
- No sequential characters
- No repetitive letters
- No real or context-specific words
- Change default passwords
- Use trusted password managers
- Enable 2FA or MFA for sensitive apps
- Allow use of all characters
- Set maximum password length to prevent denial of service
- Don’t silently truncate passwords
- Include password strength meter
- Salt password hashes
- Use modern hashing algorithms
- Show generic error messages
- Use TLS or other strong transport layer for the login page
- Ensure password change requires the user’s current password
- Enable the «paste» functionality
- Alert users of logins from new devices or places
Improve Account Lockout Threshold
An account lockout is a double-edged sword. On the one hand, it is one of the most common and effective protections against brute-force attacks because the account will simply be locked after a certain number of failed attempts.
On the other hand, account lockouts can easily create a denial-of-service situation. Hackers can launch automated attacks against all users in an organization, creating massive account lockouts and flooding customer care teams with calls from users. The cost of downtime and reputation risks would be tremendous.
Another scenario is when a user was in a rush or agitated and misspelled their email or password a couple of times. If the account lockout threshold is too low, it may trigger an accidental lockout.
Unfortunately, there’s no silver bullet that would solve the account lockout dilemma. It is the responsibility of each business to find a happy medium between security and operational efficiency. When defining the account lockout threshold, it’s important to calculate how many guesses attackers can have per day and slow them down by adjusting the account lockout threshold, duration, and reset settings accordingly.
Show Generic Errors
Error handling is another leeway for malicious actors to gather information and get in. If error messages are very specific, they make the hacker’s job way easier because they’ll know exactly what went wrong, what technologies and framework versions are used and can plan their attack accordingly.
For example, when a bad guy tries to log in using someone else’s credentials, and they see “Login failed; account disabled”, they won’t waste their time and move on to another account. Or worse, the user’s name may be revealed in the message itself, like “Login for user Boo: invalid password”.
That’s why it’s better to show generic error messages for registration, login of an existing user, and password recovery.
Account creation
A link to activate your account has been emailed to the address provided.
Welcome! You have signed up successfully.
Login
Login failed; invalid user ID or password.
Login failed; invalid password.
Password recovery
If that email address is in our database, we will send you an email to reset your password.”
This email address doesn’t exist in our database.
Another aspect to consider is the processing time. It should be the same regardless of the outcome so that the hacker couldn’t perform a time-based attack.
For example, when using the “quick exit” approach, the app will quickly throw an error if the user doesn’t exist. However, if the user does exist, but the password is incorrect, the app will go through more steps and take longer to respond. This allows the hacker to differentiate between a wrong username and password based on error response time.
It’s also crucial to ensure that no information is leaked through the URL. The app may return a generic message to the user, but a different HTTP error code depending on a successful (200 OK) or failed login (403 Forbidden).
While generic messages make reconnaissance harder for hackers, they can confuse consumers and negatively affect app adoption and user retention. So, finding a balance between usability and security is something each company should define on their own.
Ditch Security Questions
Security questions are no longer considered an acceptable authentication mechanism. It’s also worth noting that using a password in combination with a security question does not equal MFA because the factor in both cases is the same – something you know.
There are two types of security questions – user-defined and system-defined, and both are easy to compromise. Let’s have a look at common user-defined security questions and why they are bad:
What is your mom’s date of birth?
Can be discovered through social media
What is your favorite color?
A very small range of likely answers
What was your first car?
Can be discovered through social media or easily predicted
What is your pet’s name?
Pet names aren’t that unique, right?
What is your memorable date?
Users tend to provide their birth date or a wedding date, which can be sourced from socials
Of course, you can come up with more intricate questions like ‘What is the name of a college you applied to but didn’t attend?’ or ‘What is the surname of your math teacher in 7th grade?’ But are you sure all users remember those very well? A solution here is to provide a list of questions to choose from, but still, there’s no guarantee the answers won’t be predicted.
Back in 2015, Google’s research confirmed that security questions are either secure or easy to remember, but never both. While 40% of users couldn’t recall answers to their security question, 37% provided false answers deliberately, trying to make them harder to guess but achieving the exact opposite.
As for system-defined questions, they rely on the information already logged into the system, like the user’s name, date of birth, or address. The latter, however, can also be discovered through social media or dark web dumps.
Update Your Frameworks
Implementing a secure session management module is quite challenging as it combines authentication, user HTTP traffic, and access controls enforced by the web app. That’s why it’s recommended to use built-in session management features and implementation guides offered by well-known frameworks rather than code them on your own.
At the same time, even broadly adopted and well-tested frameworks may contain vulnerabilities. So, make sure to use the latest versions of frameworks that have fixes to known vulnerabilities. Additionally, change the default configuration to enhance your app’s security.
Generate Secure Session ID
The default session ID name can reveal the technologies and programming languages used by the web application. For example, PHPSESSID is indicative of PHP, JSESSIONID is generated by J2EE, whereas CFID & CFTOKEN suggests the app is built with ColdFusion. Therefore, the default name should be changed to something generic and not highly descriptive.
The session ID length matters. Like passwords, it should be long enough to prevent automated attacks; OWASP recommends at least 128 bits; however, this number is not rigid and other implementation details should be factored in.
The session ID should also have an effective entropy. In other words, it should be random and unpredictable to withstand statistical analysis techniques. One can achieve that with a credible CSPRNG (Cryptographically Secure Pseudorandom Number Generator).
The session objects and properties, like the user’s IP address, e-mail, access rights, or last login, must be stored on the server in a protected session management database or repository.
Last but certainly not least, the session ID must be unique, meaning a current session cannot contain duplicated IDs.
Choose Right Session ID Exchange Mechanism
The web app and the user need a certain mechanism to share and exchange the session ID. There are several ways to do this – with cookies, URL parameters, URL arguments on GET requests, or body arguments on POST requests.
When choosing a suitable session ID exchange mechanism, check if it allows defining advanced token properties like token expiration date and time, and granular usage policies. HTTP cookies are some of the most widely used session ID exchange mechanisms because they offer such capabilities and more.
URL parameters, on the other hand, are considered an outdated session ID exchange mechanism as they can reveal the session ID in the URL and allow hackers to perform session fixation attacks or other ID manipulations.
Another point to consider is that even though the app uses cookies by default, it may still accept other exchange mechanisms or switch from cookies to URL parameters under certain conditions. Therefore, rigorous testing is required to define how the app processes and manages session IDs in different scenarios and ensure it relies exclusively on cookies.
Implement Controls against Eavesdropping
Session IDs can be intercepted or stolen by eavesdropping on the network traffic. To prevent this from happening, web apps should implement transport layer protection.
Transport Layer Security (TLS) is one of the most modern protocols for encrypting communication between a web application and a server.
Naturally, web developers should use the latest TLS version because it’s faster and less vulnerable than its predecessors; at the time of writing, it’s TLS 1.3.
TLS should be applied to all pages regardless of their sensitivity. Otherwise, you provide a loophole for a bad actor to snoop session tokens or inject malicious JavaScript code to execute other attacks. For the same reasons, there should be no mixing of TLS and non-TLS content. Pages available over TLS cannot contain any JavaScript or CSS files loaded over insecure HTTP.
While TLS shields the data in transit, it doesn’t protect the data that has reached the system, such as that stored in the cache of the user’s browser.
Renew Session ID after Privilege Change
It is essential to ensure that your web application does not use a previously assigned token when the user’s privilege level changes. For example, when the user switches from a regular user to an administrator or superuser, the app should ignore old session IDs and generate a current one.
OWASP also recommends assigning a different session ID when the user goes from an anonymous visitor to an authenticated one. The latter helps eliminate the risk of binding the user session between the two states. The session ID regeneration is vital to prevent session fixation attacks.
Set Session Expiration Timeouts
Session expiration timeouts are helpful in that they limit the time a bad actor has to hijack the session. So, the shorter the session duration, the better. That’s why highly sensitive apps offer only 2-5 minutes before the user needs to reauthenticate again.
Of course, the session expiration interval depends on the app’s nature and actual use cases. If we’re talking about an office employee, they’ll need 8 hours of active session time, provided all of their tasks are related to interacting with the app.
There are several types of timeouts, such as idle, absolute, and renewal ones. Idle timeouts are enforced when there’s no new activity after a specific time. Idle timeouts are meant to shorten the time a hacker can guess a valid session ID. On the flip side, if the session is already hijacked, the attacker can periodically create some activity to prolong the session.
Absolute timeouts set the maximum time a session can be active, automatically closing it upon expiration. During renewal timeouts, a new session ID is generated in the middle of the current session regardless of the user activity, and the previous ID is invalidated as soon as the user sends a new request.
Once the session limit is reached, the web app should invalidate the session on the client and server sides so that the attacker can’t manipulate client parameters for tracking time, such as the number of minutes since the login.
Detect & Monitor Session Anomalies
Web applications should have built-in anomaly detection capabilities to alert users of unusual behavior or terminate suspicious sessions. Here are things that indicate a possible intrusion:
- different session IDs are tried from the same IP address in a sequential manner
- an existing cookie is deleted or modified
- a new cookie is added
- the session ID from another user is reused
- the user’s location changes in the middle of a session
Web applications should log session info throughout its entire life cycle, from creation and renewal to session ID destruction. Events like login and logout, failed login attempts, simultaneous logins, privilege changes, and high-impact transactions should be logged too. The session ID itself must be logged as a salted hash.
As for the client-facing capabilities, users should be able to view details about active sessions, connected devices, and IP addresses. They should receive notifications about concurrent logins and have an opportunity to end sessions remotely on all devices.
Go Passwordless
If there are so many issues with passwords, why use them at all? Many businesses have already adopted or intend to adopt passwordless authentication. According to Bitwarden’s 2022 survey, 41% out of 800 IT decision-makers believe passwordless authentication improves security, whereas the rest note its effect on increasing workplace productivity, better user experience, and reduced help desk service.
On top of that, if your web app connects to a third-party application, you don’t want the latter to store users’ login credentials because it increases the chance of breach and you have no control over the third-party app’s security. Here, using passwordless authentication protocols is the only option.
Here are some of the most known authentication protocols that require no password.
- OAth 2.0 – an open-source authorization framework that enables a third-party app to get limited access to an HTTP service. Instead of relying on the user’s credentials, the third-party app is issued a special access token. OAth 2.0 is used by big names like Meta, Google, Twitter, and Microsoft.
- OpenID – an open-source, decentralized technology that allows using one account for accessing multiple websites. Basically, you share your credentials with a single identity provider you trust and then log in with this identity provider without revealing your actual credentials. Over 50K websites accept OpenID for logins.
- SAML – Security Assertion Markup Language. Similarly to OpenID, SAML enables access to multiple web apps with one set of login credentials. The difference is that it’s XML-based, offers more flexibility, and is better fitted for enterprise environments.
- FIDO – stands for Fast Identity Online. The FIDO protocols rely on public key cryptography techniques. When registering on a website, the user’s device generates a key pair, retaining the private key and registering the public key with the online service. To authenticate, the user needs to prove the possession of the private key by unlocking it locally on their device by entering a PIN, speaking into a microphone, inserting a second-factor device, swiping a finger, etc.
Invest in Penetration Testing
Penetration testing is a type of testing that simulates a hacker’s attack in a controlled environment. Penetration testers use a combination of security tools like vulnerability scanners and manual techniques used by real-life attackers. This makes penetration testing fundamental to improving a company’s security posture.
Penetration testing is an indispensable part of compliance regulations like HIPAA, SOC 2, or PCI-DSS, which confirms its effectiveness in discovering security gaps and closing them timely.
We at QAwerk help startups and established companies thoroughly test their authentication modules, uncover potential threats, and find effective ways to patch those vulnerabilities. Our penetration testing checklist includes all of the mentioned points and more depending on the tech peculiarities of your product.
Besides a dynamic analysis of your app, we can also examine the source code before a major release or new product launch so that you can deliver new capabilities to consumers with a piece of mind. If you’d like to learn more about how we can help you future-proof your software against hackers and what our penetration testing process looks like, feel free to email us. We offer free, non-binding consultations to see if we’re the right fit for your needs.
Summing Up
Broken authentication is among the top ten web vulnerabilities classified by OWASP. Even though identification and authentication failures have reduced over the last couple of years thanks to standardized frameworks, they still pose a considerable risk and are exploited by bad actors daily.
Aligning your app with the best security practices for credential management and session management, educating employees on social engineering and online hygiene, and performing regular security audits by a qualified party will save you from data breaches and associated ramifications.