This article is also available as a TechRepublic download.
The seventh installment in the 2007 OWASP Top 10 series takes a look at broken authentication and session management vulnerabilities. I'll explain the nature of this weakness followed by recommendations for protecting Web applications from attacks related to this security problem.
Broken authentication and session management cover a lot of ground. In fact, it includes just about everything having to do with user authentication and the management of active sessions. At a high level, weaknesses in authentication and session management can result in the compromise of user and system administrator access. Further, session hijacking -- resulting in the compromise of sensitive information -- becomes more probable.
The OWASP documentation defines this category of vulnerabilities as weaknesses most often introduced through ancillary authentication functions such as logout, password management, timeout, remember me, secret question, and account update.
Passwords at rest, or stored, must be protected. Two ways to accomplish this include hashing and encryption. When a password is hashed, it's run through a hashing algorithm that creates a string of characters. This string of characters, known as a hash value, cannot be cracked to arrive at the original password. This is the most secure method of password storage.
Encryption is similar to hashing, except that it's possible to derive the original password from the cipher text. Although this is better than storing passwords in plain text, it still provides attackers with a potentially exploitable vulnerability.
Finally, NEVER hard-code passwords in Web application source code.
Protection of credentials in transit
No matter how well you protect user credentials at rest, they'll have to make the trip to a server at some point. That trip presents another opportunity for password compromise.
The first rule is to never send passwords in plain text. Many developers solve this problem by sending the hash value of the password instead. The server looks up the password hash associated with the user account and compares it to the hash value received from the client. If they're the same, the user is authenticated.
But what happens if an attacker intercepts the hash value as it travels from the client to the authenticating server? If an attacker is able to pluck a hash value from a packet, he can retransmit it with the user ID to gain unauthorized resource access.
To discourage the compromise of user credentials, consider using SSL to encrypt all session traffic. In this way, an attacker can't easily locate the user ID and password hash value. It also protects other sensitive data passing between client and server.
Protection of session IDs
This vulnerability is similar to protecting credentials in transit. If an attacker grabs the session ID from a packet, she or he can hijack the session. Session hijacking can result in unauthorized access to all resources available to the actual authenticated user. Some standards or guidelines to consider when combating this security risk include:
- Session IDs should be complex.
- Session IDs should change often during the session.
- Systems should never accept user-selected session IDs.
- Session IDs should never be included in URLs.
Even with these safeguards in place, the best way to protect the session ID is to use SSL for any session over which a user gains access to critical or sensitive information assets.
Protection of account lists
One way to hinder the unauthorized use of user credentials is to protect the list of authorized user accounts. By itself this safeguard is not very effective, but as part of an overall Web application security program, it helps to increase the work factor for a would-be attacker.
Management of application component trust relationships
Web application components should not possess implicit trust relationships with other components. Instead, each component should require other components to authenticate before passing sensitive information.
Once your policy, standards, and guidelines are in place, you need to validate compliance. I recommend two approaches. First, perform code reviews. However, you might not have the resources to manually review every line of code. If you're unable to implement automated source code security-scanning software, at least perform spot checks of critical code elements.
Second, perform penetration testing. Regular penetration tests help identify weaknesses in how Web application components interact with users as well as other application components.
The final word
The following is a list of considerations, based on those provided by the OWASP, for dealing with broken authentication and session management:
- Do not accept new, preset, or invalid session identifiers from the URL in the request.
- Limit or rid your code of custom cookies for authentication or session management purposes.
- Use a single authentication mechanism with appropriate strength and number of factors. The mechanism you select should not be overly complex -- complexity is the enemy of security.
- Do not allow a login process to start from an unencrypted page.
- Consider regenerating a new session upon successful authentication or privilege level change.
- Ensure that every page has a logout link.
- Use a timeout period that automatically logs out an inactive session. The timeout period should take into consideration the sensitivity of the information accessed.
- Use only strong identity verification questions for password resets, etc. Mother's maiden name, for example, is easily obtained information.
- Do not expose any session identifiers or any portion of valid credentials in URLs or logs.
In general, authentication and session security are critical to Web application security. The most hardened application is wide open to attack if weak session and password management processes are in place.