Cybercrime is escalating—and it’s a big issue for companies handling sensitive user data.
It’s a risk and reality for international fortune companies (e.g. Quora.com and Marriot) with access to millions of user’s records face—experiencing massive sensitive data breaches. Even if we consider this past decade as a “Golden Age” of technology, the truth is that none of the new tech-stack will remedy the issue of human error. While using the latest technology might be strongly recommended, not understanding how the technology works, the possible security issues, and the basics of secure development practices is also a big problem.
Authentication and user session management are particularly vulnerable areas. Although they have many pre-made solutions and implementations, such vulnerabilities still make the “OWASP Top 10 Web Application Security Risks” list of the most critical kinds of today’s web applications vulnerabilities. Recently user authentication and session management weaknesses were even “honored” with a silver medal for being among the biggest threats to application security.
Authentication tokens are one of the most important factors while handling registered application users. These special randomly generated lines of characters are used to authenticate users after they enter their login credentials. Without tokens, users would need to enter their credentials on each authenticated action which would be very uncomfortable. Because tokens are one of the core attributes in authentication mechanism, there’s little doubt they are one of top attack and investigation vectors for cyber-criminals trying to compromise portals authentication mechanism.
In this article, we’ll review five common mistakes and other key considerations while working with authentication tokens.
1. You are not using strong tokens.
First, let’s talk about applications which are implemented with stateful authentication. The authentication state in these applications is just a simple file (or data/record) that’s stored in temporary storage. In addition to the file, users get an identification (or session) token.
You should always keep track of how strong and un-guessable your session tokens are. They should be generated in a manner that any attacker who obtained a large sample of session ID’s from the application could never predict or extrapolate the tokens issued to other users.
Some general rules for generating strong tokens:
- Use an extremely large set of possible values.
- Work with a strong source of pseudorandomness, ensuring an even and unpredictable spread of tokens across the range of possible values.
- Make the tokens long enough (at least 16 bytes).
- Posting various automatically generated secrets (brute-force) would take a very long time to guess authentication token.
- The latest popular frameworks usually already have pre-made modules generating strong tokens, so you don’t need to reinvent the wheel.
- Sometimes, generating robust tokens may take a few seconds which could be mistaken for slower service and frustrate users.
- Frameworks are targeted and then compromised just for being popular. Engineers should be able to validate the strength of the algorithm, for which special cryptographic skillset might be needed. To avoid an issue from arising, at least keep your frameworks updated.
- Token names usually are attached to underneath technologies such as frameworks from .NET or JAVA. As a rule, engineers usually leave the token name alone which might help attackers understand what technologies are used beneath the service, and after that better understand ways how to hack them.
2. You transport on an open connection
When actual tokens are safe, it is a good idea to put them in a bunker, just in case. Try to keep your diamonds out of sight by transporting your tokens only through HTTPS so that the token data is invisible to outside viewers. Having mixed content rails in your website might not be a good idea.
Suppose all your web pages are under HTTPS protocol, but for some reason, you thought that loading that special image (or style file) would be a lot better on the open channel. In the end, if token storages are not secured properly, an attacker could steal your authentication secrets just by looking at those extra file requests without needing to break the username-password lock.
3. Your token storage is not bulletproof.
When application security is at the top of the list, you should store tokens in cookie storage. Two special cookie attributes in mind are:
- Secure cookies are important in case you forget to transport all your applications under HTTPS.
Establish path rules for cookies. Adding the stricter path (same-site) policy could help, too. If your main website (e.g. example.com) went through pre-production audit and someone forgot to put the correct domain attribute for the cookie, hackers could steal the token if you have a not-so-secure subdomain website (e.g. help.example.com) being hosted on the side.
- While a strict security audit might be done for the main site, it is very usual to test lower-funded children portals less. Having a same-site policy will minimize the risk of breaking main site authentication through supporting websites.
- This will help ensure that authentication mechanisms for both sites are independent and prevent unexpected authentication issues from happening while doing manual or automation testing.
- It is not easy to identify and track each page where a certain authentication token is really needed. It might be necessary to document and review each case separately.
- Cross-domain authentication token support will not work anymore (so think twice before using it).
4. You don’t manage token expiration time.
Token renewal is a process of generating a new token after a set, recurring time period. Renewal time is just a variable which defines in minutes or seconds how often the renewal of token will happen. The general recommendation here is to refresh the token as often as possible. It’s best not to allow one token to be valid for a long time. Token expiration techniques can be split into two categories.
Automatic token expiration techniques including:
Idle – The application should keep track of user activity. If there is no activity after 10–15 minutes, end the user’s session (or invalidate the stateless token). The user should definitely be informed that they are going to be logged out because of inactivity. A usual approach is implementing pop-up modal with a choice to cancel or proceed using the website.
Absolute – Think of this as a warranty time for the user authentication token. No matter what, for security reasons, after any long period (for example, 24 hours), any token should be terminated, and the user should be forced to log in again.
Renewal – If the user is active, the authentication token should automatically be renewed every 10-15 minutes. In the event of a single token theft attack, the action time of doing harm is minimized.
Manual token expiration including:
Logout button - Always destroy a user’s session when the user clicks the logout button. This way the same token will not be used again (or even worse, in parallel with newer ones).
Browser close – If it is possible to track browser-closing events, it’s smart to invalidate the session with tokens right before closing. While it might not be very bulletproof, this combined with automatic expiration techniques could work for added security.
Refresh your tokens on each privilege change - Was it just a simple login? Or maybe a changed password? Either way, renew your tokens. This can really help while preventing token fixation attacks.
Consider requiring users to re-authenticate.
It’s an additional safety step for the logged and authorized user to take before serious actions such as conducting banking transactions or password changes. Never count on active authentication alone. Before submitting solid action require users to re-enter their credentials or ask users to provide some alternative (temporary) PIN numbers or smart IDs. This might require third-party software or additional investment into physical gadgets. However, skipping this step could lead to a very serious security breach which could then have a ripple effect on bigger financial and reputation losses for the organization.
5. You allow the user to have multiple logins at the same time.
When thinking about secure authentication management, it can mean having less comfortable user experience at times.
For robust systems, consider outlawing parallel authentications for the same user. From the implementation standpoint, we have multiple options to remedy this. A simple way to address parallel authentication issues is to store temporary attributes somewhere inside the user’s row in a database or cache. A couple of examples include “logged = true” and “user agent = IE 11.1.1” (or maybe even the active token). Storing key attributes can help make sure that the single account will never be used by two different people at the same time. Obviously, if this happens, someone has to be kicked out.
Key points to consider while outlawing parallel authentication for users:
- Even if the token key is stolen and attached in an attacker’s computer, the application administrator (and even the original user) can be notified and respond quickly.
- Active session hijacking becomes pretty much impossible.
- If there is a requirement to keep the same user session between web and mobile apps, the implementation will not be straightforward.
- Bumping into obstacles while trying to run those automatic tests might become a ritual for a while.
Overall, before implementing authentication restrictions, think about what is more important for your application clients—convenience or security. And if it’s the latter, don’t hesitate to take drastic measures on parallel authentication handling.
What about modern stateless authentication?
In this section, I will focus on JSON Web Tokens (JWT) because they are currently the most widely used token standard for handling stateless authentication. From a security perspective, one of the most important JWT parts is hashing secrets.
Some considerations for using strong hashing secrets are:
- They should be nearly impossible to guess—preferably long and random.
- Developers should consider using multiple secrets for different environments.
- They should only be visible and actionable from the server side so that it would be impossible to hijack and use the data for custom token generation.
As for JWT itself, never trust token data on the client side and even consider hiding it from there. Because hashing keys should only be reached from the server it will be impossible to verify if the client side accepted JWT attributes were not malformed by an attacker.
Another challenging aspect of JWT is handling the expiration. How can you invalidate this token, when the fixed expiration time is within itself and it cannot be changed without breaking tokens consistency? To address JWT expiration challenges, consider these two solutions:
1. Track the latest user token in the database with its activity status (either active or invalid). Even if the token expiration time is within range, you can tell if the token can still be used for authentication by quickly checking its activity status record.
2. Use server-side cache storage. Each valid token can be cached and removed from storage when needed. In addition to verifying JWT, the application could double check if it is still in the state of active usage.
Although JWT tokens might be considered a perfect mechanism when going stateless, keeping track of them (having “some sort of state”) on the server might still be preferable.
Take action and track data.
Tracking each suspicious action might still be a good idea, even if you followed all the secure token rules. Responding quickly might help a lot more than any million-dollar security system. What do you do when some serious attack patterns are detected, such as a sudden change in expected IP addresses or unusually high load on login service? Destroying a harmful session is a usual first step, but never forget to do further investigation and don’t hesitate to take drastic action (such as IP blocking, temporarily disabling critical actions like money withdrawal, transactions and etc.) if necessary. While authentication tokens might seem like a small piece in overall applications security, we still should think about it as more as a foundation than just one brick. After all, a strong and safe house will always need a strong foundation.