Web Application Security Basics- Authentication and Session Management (Part I)
Authentication is used to establish the identity of a user. So this can be considered as the main gate of any secure web application. Registration of new users is the first step towards authentication.
Positive patterns:
- When registering new users a username an email address and a password should be requested at the very minimum. Also the email address should be verified before enabling the account.
- If multi factor authentication is implemented then the relevant data should be requested as well.
- If the “forgot password” feature requires answering to security questions they should be setup during this phase of the application.
Preventing automated registration:
- If there are concerns about attackers exploiting the automated registration for malicious purposes using a CAPCHA is encouraged. (But it should be kept in mind that there is a trade-off since this will reduce the usability of of your application)
- An alternative to using CAPCHA is connection throttling; After a user is created, your application should enforce a time limit of 15 minutes before another user can be registered from the MAC address or IP address.
- One technique that may help stave off automated registration abuse is to add an additional form component, such as a text field, and then hide it with CSS by positioning the component off-page or use some other method to make it invisible to users. A normal user would never see or be able to fill this “hidden” text field with any data.
<input type=”text” name=”company” value=”Input Company Name”
style=”position:absolute;left:-1000px;”>
Anything other than an empty string for this field should be considered as a registration attempt from a bot which can be logged and ignored.
The basic workflow of registering new users
Step 1: Anonymous session created on first hit
- When a user first visits your website, J2EE automatically creates a session for them and sets a JSESSIONID cookie even before that user logs in. This can carries both good and bad effects as with anything.
- The usefulness of this is that you may wish to track which products a user has looked at so you can provide targeted advertising or otherwise change and improve the user experience.
- The danger is that an attacker can easily generate an active session ID at any time. This can be used to trick a user to become a victim of session fixation.
Step 2: Starting HTTPS and encryption in transit
It is critical that you plan to deliver your login form using HTTPS. Securely submitting username and password over HTTPS alone does not provide the necessary security for your login workflow.
If the login form is submitted over HTTP and an attacker modifies the login form the impact it can make can be significant. ( An attacker could insert a keylogger, change the form HTTP POST action to submit your password to a hacker-controlled website, or inject JavaScript to exfiltrate the password to another hacker-controlled website when you click Submit)
Step 3: Processing and verifying credentials
In the previous step he user submits the username and password via HTTPS. When the username and password is submitted , the username is first looked up in the database and if it doesn’t exist a generic error message should be given like “Username/Password combination is invalid” . Giving an error message specifying the exact error will help an attacker exploit it against the system.
If the username matches then the submitted password is hashed using the same algorithm which was used to store it and the salt chosen . If the user’s cyphertext matches the cyphertext that is stored in the database and if the user competes the multi-factor authentication check successfully, the user is authenticated and logged into the system.
Step 4 : Start the users authenticated session
After an user is logged in the anonymous session created in step 1 is invalidated and a new session is created.
Most java frameworks will create session cookies automatically with the session. URL rewriting should be disabled as the session ID can be reflected via the url if enabled.
eg:
https://www.somesite.com/myAccount.jsp;jsessionid= 902B45163DCCFAE90748DDB358CC7502
This is used as an alternative to maintain the session when cookies are disabled in the browser. Instead of using url rewriting and exposing sensitive data it is a better option to prompt the user to enable cookies in the browser. To ensure the web application does not support url rewriting following configuration can be used in the web.xml .
In Apache tomcat following lines can be used in server.xml to disable url rewriting.
<Context docBase=”/webapps/myapp” path=”/myapp”
disableURLRewriting=”true”>
Step 5: User actions
once session is started user will start performing actions. With each request, the browser will automatically include the authenticated session cookie, and the server will validate that the cookie’s session ID refers to an active session on the server. This i show the authenticated requests are validated.
Step 6: Re-authentication for sensitive operations.
Sensitive operations like changing password, privilege assignments and high value money transfers needs re-authentication of the user. This would prevent an attacker who has hijacked a session from a user performing those sensitive operations. This also helps to mitigate CSRF class attacks in addition to minimizing the effect of various forms of session theft.
Step 7: Idle Timeout
Setting an idle timeout will better secure your web application . Java EE has a default session timeout mechanism supported by most Java web frameworks. In web.xml, the simple directive will force sessions of inactive users to invalidate server-side once users are inactive for 20 minutes.
Step 8: Absolute timeout
Setting an absolute timeout will help to prevent an attacker from keeping an hijacked session alive indefinitely. Setting a absolute time can be done using java filters.
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws ServletException, IOException {
if ((CurrentTime — LoginTime) > AbsoluteTimeoutLength) {
request.getSession().invalidate();
}
//forward on to other filters
chain.doFilter(request, response);
}
Step 9 : Logout
Encouraging users to logout from the web application is a good security measure. A logout button should appear prominently on your website,conventionally in the upper-right corner of every page in your site.
When clicked, the logout button should send a request to the server that triggers logic, which will immediately destroy the current active session by a call to HttpSession.invalidate() .
Attacks against authentication
Session Hijacking
Session hijacking is a result of an attacker stealing a session id of an authenticated user and making impersonated requests as the user. An attacker can steal the session id using many ways such as by forcing a victim to use a specific session id or even simply by logging in using the victims computer when left in the open.
Cross site scripting is another way of an attacker compromising the session through cookie theft.
Session fixation
Session fixation is a specialized form of session hijacking. Session fixation works as follows.
1. First the attacker visits your website to obtain a valid session ID.
2. The attacker then creates a URL for the vulnerable website that includes this session identifier as an HTTP GET parameter value, for example using a URL rewriting vulnerability.
3. The attacker tricks a victim into clicking on the URL to visit the vulnerable website.
4. The vulnerable website recognizes the session ID in the URL and resumes the session that was started by the attacker.
5. Once the victim logs in, the attacker is now able to compromise the victim’s session because the attacker knew the session ID before the victim even pressed the link.
The only way to prevent this is to invalidate the current session and create a new session when an user logs in to a site.
Using secure cookie properties as discussed under OWASP top 10 Broken Authentication and Session Management is important to secure the cookies.
Credential Security
Password Policy
The traditional guidelines followed when forcing strong passwords are nearly invalid in the recent times. The traditional policies that enforce at least one uppercase letter, one lowercase letter, a number, and a non-alphanumeric character is out of date since “Password1!” should be a strong password according to the above scheme but it’s not !
It is important to define policies above but still it’s a mistake to rely on that alone. Multi-factor authentication is a positive pattern.
Password Managers
It is important your application support password managers. In order for your website to be “password manager ready,” we suggest that you allow your users to choose very long passwords, but not too long.
Also, be sure to avoid complex JavaScript on your authentication form fields because that could throw off a password manager’s ability to work with your website. Lastly, it is important for your website to allow users to paste into the password form field (this can be disabled via JavaScript).
Password Storage
The first go-to algorithm for password storage in the Java ecosystem is the natively supported PBKDF2 NIST Standard KDF (Key Derivation Function). Use PBKDF2 to store the password of each user.Use a different random salt for each user. Use a iteration count that is as high as you can tolerate! The larger the iteration count the more secure your password storage system is.
Salt
Because PBKFF2 and scrypt produce predictable output, if two users have the same password, their password ciphertext will be the same. Adding a salt will ensure that two password values will not have the same value.
Whenever a user creates or changes his or her password, create a 32-character random value, the salt. Then, add the salt to the password before you protect it with PBKDF2, scrypt, or your specialized HMAC setup. Be sure to store the salt along with your hashed password in the database so that you can use the salt again on subsequent authentication attempts.
Originally published at http://neatrick.wordpress.com on October 1, 2015.