It has become very common for almost all websites to have a login functionality for their users. A user sign up with an email or username and a password without thinking twice, as it has become easier to visit the website back again with the help of browser's or plugin's caching and third-party authentication services.
Unfortunately, the security threats are also on the rise and it has become easier for hackers to sell the credentials on the dark web or publish breached data on paste sites, hijack social media accounts for click baiting or fund transactions.
We will look into how the authentication works, how attackers compromise an account and how to defend against such attacks.
Authentication framework is provided by HTTP, which is used by a server to challenge a client request with a
401 status code (meaning Unauthorised) and provides information on how to authorise with a
WWW-Authenticate response header. The client that wants to authenticate itself with the server has to include
Authorization request header with credentials.
The most common type of Authentication is a
Basic, included in the
Authorization header as below:
//syntax Authorization: <type> <credentials> //example Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Other authentication types can be found at the IANA registry of Authentication schemes.
basic authentication, the client obtains username and password from user, constructs the user-pass by concatenating the username, a single colon (":") character, and the password (generating the string
username:password). It then encodes the user-pass into octet sequence, and finally encodes the octet sequence using Base64 into a sequence of US-ASCII characters.
If the user agent wishes to send the username "Aladdin" and password "open sesame", it would use the following header field:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
As the username and password are passed over the network as clear text (it is base64 encoded, but base64 is a reversible encoding), the basic authentication scheme is not secure. HTTPS/TLS should be used with basic authentication.
For more information refer RFC 7617.
The following are the common types of automated attacks that attackers use:
Hackers attempt to get past the authentication against a single account by guessing passwords. These attempts have higher chance of success by using scripts which try numerous commonly used passwords from a dictionary and from millions of leaked passwords obtained from previous data breaches.
This type of attack is made by testing username and password pairs obtained from the breach of another website. Check whether your email, phone or password is in a data breach in the website haveibeenpwned.com.
In this type of attack a single weak password is tested against a large number of different accounts.
Lets look at the various ways of protecting against such attacks
It is now common to use social media account like Facebook or Google account to authenticate a user in a website. This is more convenient as the user does not have to use or remember a password. It is not considered safe to allow third-party apps to store username/password combo. For this and other use cases authentication protocols can be used to protect the user's data. Examples include OAuth, OpenId, SAML and FIDO.
OAuth or OpenID requires users to usually use their personal email addresses as usernames. For business users, consider using
Single sign-on (SSO)identity providers like Okta, OneLogin, wherein they use their business email to login.
Not all users have Facebook or Gmail or other social media accounts to login. That means websites still needs the usual way of sign-up, login & logout using personal email or username of choice and password apart from third-party authentication. There are many considerations to be taken before implementing your own authentication system:
- It should be case-insensitive, i.e, a username "Bob" and "bob" should be the same user.
- It should be unique.
- Use a separate display name, when a user has a public profile & avoid use of email address as display name as it invites spam.
- Validate and verify email addresses, by checking for valid characters and by sending a verification link with token, only then send further transactional emails.
- Ban disposable emails generated by services like 10 Minute Mail or Mailinator.
- Do not allow login with sensitive accounts (eg. internal accounts used for DB) to any frontend user interface.
- Do NOT use the same authentication solution (e.g. IDP / AD) used internally for unsecured access (e.g. public access / DMZ)
- Minimum length of the password is enforced by the application and less than 8 characters is considered to be weak,
- Maximum password length should not be set too low, as it will prevent users from creating passphrase. Some set it to 64 characters due to limitations in hashing algorithms, check out more in OWASP Password Storage Cheat Sheet
- Maximum password length should be set in order to prevent long password denial of service attack.
- Do not truncate password if the password set by user exceeds the limit, use pre-hashing algorithm like the PBKDF2.
- Allow usage of all characters including unicode and whitespace.
- Allow credential rotation (change/resetting password) when password is compromised. Password-reset links should expire after user uses them or after 30 minutes to prevent an attacker from abusing stale reset links. To know about password resetting mechanisms, read OWASP Forgot Password Cheat Sheet.
- Use a library for calculating the strength of the password, be careful while choosing, check for less dependencies and maintainability status.
- Use Pwned Passwords API to check the password entered is in the list of previously breached passwords.
- For revalidating the users when they login again, the passwords should be stored in the database securely using a cryptographic technique, detailed well in OWASP Password Storage Cheat Sheet.
The passwords are not stored as is but as hashes, for this a good hashing algorithm should be chosen, so that even if the attacker gets the hashed password it would take forever to crack (it is not possible to decrypt hashes back to original password).
These are the steps which the attacker uses to crack the password from hashes.
- Select a password you think the victim has chosen
- Calculate the hash
- Compare the hash you calculated to the hash of the victim. If they match, you have correctly "cracked" the hash and now know the plaintext value of their password.
Read password security requirements to know more on Password security considerations.
It is best to have an additional layer of security with Multi-factor Authentication over secure password storage, to be effective against attacks like Brute-force, credential stuffing and password spraying. Microsoft suggests that it would have prevented 99.9% password compromises with MFA. It requires a returning user to provide evidence about their identity with at least two of the following four categories of information: something they know, something they have, something they are and their location.
Many use authentication mobile apps like Google authenticator and Microsoft authenticator that can be synced with a website during sign-up, and later can be used to generate random pins for logging in successfully.
To get guidance on implementing MFA, read OWASP Multi-Factor Authentication Cheat Sheet.
CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart), asks users to perform various image recognition tasks that are trivial for humans but tricky for computers. It can help to prevent automated login attempts and user enumerated attacks (testing each username from a list to see whether it exists on your website).
CAPTCHAs are not perfect and can be defeated by attackers using machine learning techniques, or by paying human users to complete a task, but it still prevents most common hacking attempts.
Make sure that CAPTCHAs are user friendly for regular users by only requiring a CAPTCHA to be solved after a small number of failed login attempts, rather than requiring it from the very first login and make it less complex 🙂.
It is equally important to have a secure logout functionality for your users, to prevent from session hijacking attacks.
Logout function should clear the session cookie in the browser, and invalidate the session identifier if you are storing it on the server side. This protects against attackers who attempt to intercept session cookies and attempt to reestablish a session using a stolen cookie. The session cookie is cleared by sending back an HTTP response containing a
Set-Cookie header with a blank value and set the
Expires(or Max-Age) attribute to a date from the past (in case a persistent cookie is being used):
Set-Cookie: id=; Expires=Friday, 17-May-03 18:45:00 GMT.
The other ways of protecting against attacks include using Password Managers and re-authentication.
As attackers find ways to security loopholes, one has to find better ways of protecting against it, and by enabling logging and monitoring of authentication one can detect attacks/failures on a real-time basis.