Broken Authentication and Session Management
Description
Authentication and session management includes all aspects of handling user authentication and managing active sessions. Authentication is a critical aspect of this process, but even solid authentication mechanisms can be undermined by flawed credential management functions, including password change, forgot my password, remember my password, account update, and other related functions. Because "walk by" attacks are likely for many web applications, all account management functions should require re-authentication even if the user has a valid session id.
Examples
Scenario #1
Airline reservations application supports URL rewriting, putting session IDs in the URL:
http://example.com/sale/saleitems; jsessionid=2P0OC2JDPX..LPSKHCJUN2JV?dest=Hawaii
An authenticated user of the site wants to let his friends know about the sale. He e-mails the above link without knowing he is also giving away his session ID. When his friends use the link they will use his session and credit card
Scenario #2
Application’s timeouts aren’t set properly. User uses a public computer to access site. Instead of selecting "logout" the user simply closes the browser tab and walks away. Attacker uses the same browser an hour later, and that browser is still authenticated.
Scenario #3
Insider or external attacker gains access to the system’s password database. User passwords are not encrypted, exposing every users’ password to the attacker.
Scenario #4
Insider or external attacker gains access to an applcations database. NetId’s are stored plain text. The attacker now has a list of user names from which to launch brute force password attacks on any other application that uses NetId’s to authenticate users.
Mitigation
When possible MSU applications should authenticate users against the MSU directory using netid and password. If netid’s are stored for authorization purposes they must be encrypted. By relying on the directory server to authenticate users many of the preventative measures listed below are met. When possible applications should not rely on their own authentication mechanism but should use provided authentication tools. Contact [email protected] for more information about the recommended authentication tools.
Password Strength
Passwords should have restrictions that require a minimum size and complexity for the password. Complexity typically requires the use of minimum combinations of alphabetic, numeric, and/or non-alphanumeric characters in a user’s password (e.g., at least one of each). Users should be required to change their password periodically. Users should be prevented from reusing previous passwords.
Password Use
Users should be restricted to a defined number of login attempts per unit of time and repeated failed login attempts should be logged. Passwords provided during failed login attempts should not be recorded, as this may expose a user’s password to whoever can gain access to this log. The system should not indicate whether it was the username or password that was wrong if a login attempt fails. Users should be informed of the date/time of their last successful login and the number of failed access attempts to their account since that time.
Password Change Controls
A single password change mechanism should be used wherever users are allowed to change a password, regardless of the situation. Users should always be required to provide both their old and new password when changing their password (like all account information). If forgotten passwords are emailed to users, the system should require the user to reauthenticate whenever the user is changing their e-mail address, otherwise an attacker who temporarily has access to their session (e.g., by walking up to their computer while they are logged in) can simply change their e-mail address and request a ’forgotten’ password be mailed to them.
Password Storage
If an application needs to maintain user lists for authorization or cross-referencing it should store only the (hashed) username or netid of each user. All passwords must be stored in either hashed or encrypted form to protect them from exposure, regardless of where they are stored. Hashed form is preferred since it is not reversible. Passwords should never be hardcoded in any source code. Decryption keys must be strongly protected to ensure that they cannot be grabbed and used to decrypt the password file.
Protecting Credentials in Transit
The only effective technique is to encrypt the entire login transaction using something like SSL. Simple transformations of the password such as hashing it on the client prior to transmission provide little protection as the hashed version can simply be intercepted and retransmitted even though the actual plaintext password might not be known.
Session ID Protection
Ideally a user’ entire session should be protected via SSL. If this is done, then the session ID (e.g., session cookie) cannot be grabbed off the network, which is the biggest risk of exposure for a session ID. If SSL is not viable for performance or other reasons then session IDs themselves must be protected in other ways. First, they should never be included in the URL as they can be cached by the browser, sent in the referrer header, or accidentally forwarded to a ’friend’. Session IDs should be long, complicated, random numbers that cannot be easily guessed. Session IDs can also be changed frequently during a session to reduce how long a session ID is valid. Session IDs must be changed when switching to SSL, authenticating, or other major transitions. Session IDs chosen by a user should never be accepted.
Account Lists
If at all possible MSU applications should avoid storing user account names or netids. Systems should be designed to avoid allowing users to gain access to a list of the account names on the site. If lists of users must be presented, it is recommended that some form of pseudonym (screen name) that maps to the actual account be listed instead. That way, the pseudonym can’t be used during a login attempt or some other hack that goes after a user’s account.
Browser Caching
Authentication and session data should never be submitted as part of a GET, POST should always be used instead. Authentication pages should be marked with all varieties of the no cache tag to prevent someone from using the back button in a user’s browser to backup to the login page and resubmit the previously typed in credentials. Many browsers now support the autocomplete=false flag to prevent storing of credentials in autocomplete caches.
Trust Relationships
Your site architecture should avoid implicit trust between components whenever possible. Each component should authenticate itself to any other component it is interacting with unless there is a strong reason not to (such as performance or lack of a usable mechanism). If trust relationships are required, strong procedural and architecture mechanisms should be in place to ensure that such trust cannot be abused as the site architecture evolves over time.