Tag Archives: Session Token

CSRF Prevention in Java

What is it and why should I care?
Cross-Site Request Forgery (CSRF) is an attack where victims are forced to execute unknown and/or undesired requests onto a website where those requests are currently authenticated. CSRF exploits the fact that the “credentials” needed to perform a function on a website are generally loaded into a client-side cookie, which is then automatically transmitted with every request. By exploiting this automatic transmission, an attacker can cause a victim to execute almost any request that is not protected against CSRF.

Below is a simple image that shows how a basic CSRF attack works:

The steps are:
Step 1. The victim is lured into visiting an evil site (evil.com)
Step 2. The victim’s browser loads the evil site, which contains a hidden image whose src points to an important transaction (on good.com)
Step 3. The victim’s browser executes the transaction at good.com, thus passing along the session cookie (general authn/z mechanism)
Step 4. The transaction occurs, but the victim is unaware until later – or perhaps never − that the transaction occurred

 

 

What should I do about this possibility?
Now that we know what CSRF is, and why it is so dangerous, let’s consider some possible solutions:

Token
The classic solution to CSRF has been a per-session token (known as the synchronizer token design pattern).

The basic flow using this solution is:
Step 1. When the user logs in, a randomized string (token) is then placed in the user session
Step 2. On every form for a non-idempotent request (essentially meaning any request that changes the server-side state – which should be your HTTP POSTs), the token is placed in the form when it is submitted
Step 3. The request handler for the non-idempotent request validates that the submitted token matches the token stored in the session. If either of the tokens is missing, or if they do not match, do not process the transaction

In the past, this per-session token solution has served pretty well for most CSRF situations, but it can be time-consuming to implement and it also creates opportunities for forgetting validation on some requests.

Another solution that uses the token pattern is the ESAPI project, which has built-in CSRF protection, However, ESAPI’s CSRF solution is tied to the authentication scheme. Here is a write-up about using ESAPI’s CSRF protection.

CSRFGuard
A very good option offering solid protection against CSRF is the OWASP CSRFGuard project. This library makes it relatively easy to build CSRF protection into your application by simply mapping a filter and updating a configuration file. This is certainly a resource worth checking out.

Stateless CSRF Protection
One more thing I’d like to share is some interesting work in the area of stateless CSRF protection. When you cannot – or do not want to – maintain the user token in the server-side session state, this is a seemingly novel solution. The idea is to allow the client side to create a cookie with the CSRF token (which is then submitted on every request), and to then include the token as a request parameter. Because an attacker can not read both the cookie and the request parameter, then all the server side should have to do is validate that the token in the cookie and the request parameter match on another. This solution, to my knowledge, has yet to be widely reviewed or tested, but it is a great example of an elegant solution to a difficult problem. Only time will tell if this is the go-forward solution for stateless CSRF protection.

CSRF is a definitely a popular and dangerous attack, but with the protections described above, it is certainly manageable.

One last note: The token approach (classic or stateless) will break down when the site on which it is deployed contains XSS (Cross-Site Scripting) vulnerabilities. If attackers can XSS your site, they can read the content and extract the token you are using; this will effectively nullify the protection you have established. The lesson is simple: Fix those XSS bugs, too!

References
­­­­­­­­­­­­–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
http://www.cgisecurity.com/csrf-faq.html
http://www.jtmelton.com/2010/05/16/the-owasp-top-ten-and-esapi-part-6-cross-site-request-forgery-csrf/
https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API
https://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project

Session Fixation Prevention in Java

What is it and why should I care?
Session fixation, by most definitions, is a subclass of session hijacking. The most common basic flow is:

Step 1. Attacker gets a valid session ID from an application
Step 2. Attacker forces the victim to use that same session ID
Step 3. Attacker now knows the session ID that the victim is using and can gain access to the victim’s account

Step 2, which requires forcing the session ID on the victim, is the only real work the attacker needs to do. And even this action on the attacker’s part is often performed by simply sending the victim a link to a website with the session ID attached to the URL.

Obviously, one user being able to take over another user’s account is a serious issue, so…

What should I do about it?
Fortunately, resolving session fixation is usually fairly simple. The basic advice is:

Invalidate the user session once a successful login has occurred.

The usual basic flow to handle session fixation prevention looks like:

1. User enters correct credentials
2. System successfully authenticates user
3. Any existing session information that needs to be retained is moved to temporary location
4. Session is invalidated (HttpSession#invalidate())
5. New session is created (new session ID)
6. Any temporary data is restored to new session
7. User goes to successful login landing page using new session ID

A useful snippet of code is available from the ESAPI project that shows how to change the session identifier:

http://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java (look at the changeSessionIdentifier method)

There are other activities that you also can perform to provide additional assurance against session fixation. A number are listed below:

1. Check for session fixation if a user tries to login using a session ID that has been specifically invalidated (requires maintaining this list in some type of LRU cache)

2. Check for session fixation if a user tries to use an existing session ID already in use from another IP address (requires maintaining this data in some type of map)

3. If you notice these types of obvious malicious behavior, consider using something like AppSensor to protect your app, and to be aware of the attack

As you can see, session fixation is a serious issue, but has a pretty simple solution. Your best bet if possible is to include an appropriate solution in some “enterprise” framework (like ESAPI) so this solution applies evenly to all your applications.

References
———–
https://www.owasp.org/index.php/Session_fixation

http://www.acros.si/papers/session_fixation.pdf

http://cwe.mitre.org/data/definitions/384.html

http://projects.webappsec.org/w/page/13246960/Session%20Fixation

Secure Session Tokens

Secure Session Tokens

Of the many ways an attacker can exploit Web applications, exploiting a user’s cookies is the method most often used in the worst attacks. Typical examples of this type of attack include Cross-Site Scripting and Session Fixation.

The most valuable cookie of all is one that stores the user’s session token value, which allows a user to access authenticated areas of a website. A session token value is set as a cookie in the user’s browser during the login process of most Web applications. This same session value is also generally saved as a session variable on the host server.

When the user’s browser sends a request to a specific host name, each of its associated cookies are included in the request to the host server. The application then compares the value of both the cookie storing the session token and the stored session variable. If they match, the user is authenticated to the application. However, if the cookie storing the session token value is stolen while the session is active on the server, it is “Game Over” for the user.

Specific Problems Related to Attacks on User Cookies

A few basic problems allow exploitation of weaknesses and subsequent attacks on the user’s authentication cookie. These problems typically relate to four characteristics of a cookie:  strength, predictability, regeneration, and expiration. While fixing such problems may be inadequately for defending against attacks such as Cross-Site Scripting, it will make attacks such as Session Fixation and Credential/Session Prediction more difficult and will help mitigate weaknesses such as Insufficient Session Expiration.

Below is a WhiteHat Security cookie storing a session token value generated by an imaginary PHP application:

PHPSESSID=;

No. 1 Strength

The strength of a session token depends on the number of character spaces it has.  Just as a strong password uses more characters and a greater variety of characters, so a strong session token will include those same characteristics.

An example of a weak session token:

PHPSESSID=abcdefg;

A session token with a low number of character spaces can be brute forced, which lets an attacker cycle through possible session tokens and discover the ones that are currently authenticated. Again, the best session tokens have a very high number of characters, usually at least 20 to 25 [more characters are even better!], as well as requiring numbers and case sensitivity. Using special characters also increases the strength of a cookie.

An example of a much stronger session token:

PHPSESSID=V4J2tiM442QxeYk5wOnP;

No. 2 Predictability

Strength alone is insufficient to keep a session token secure. For example, the greater the predictability of a session token, the weaker  its strength.

An example of a strong session token based on low predictability:

PHPSESSID=eOzcMYF7IEb7XeW4756;

Secure Session Tokens

When brute force is successful in compromising session tokens, patterns in their value often become easily evident:

PHPSESSID=eOzcMYF7IEb7XeW4756;
PHPSESSID=eOzcMYF7IEb7XeW4757;
PHPSESSID=eOzcMYF7IEb7XeW4758;
PHPSESSID=eOzcMYF7IEb7XeW4759;
PHPSESSID=eOzcMYF7IEb7XeW4760;

Upon discovering this sequence, all an attacker needs to do to steal a user’s accounts is base his attack on the subsequent session tokens as they are created when the user logs in.

No. 3 Regeneration

While the importance of session token regeneration may not be immediately obvious, it is a necessary component for averting Session Fixation attacks. The WASC Threat Classification describes session fixation as “…an attack technique that forces a user’s session ID to an explicit value.” Cross-Site Scripting is usually the method used to carry out a Session Fixation attack, by either setting a cookie value for that user or stealing a session token value prior to the user logging in. Then, when the user logs in with the pre-determined session token value, the attacker can send requests to the server just as if he were that user.

The best defense against a Session Fixation attack is to “regenerate,” i.e., assign a new session token value every time a user logs in. Note, however, that if the token is changed from the pre-login value, the session can no longer be fixed.

An example of an HTTP server response setting a new cookie value for PHPSESSID post-login:

HTTP/1.1 200 OK
Server: Apache
Content-Type: text/html
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Tue, 05 Apr 2011 21:46:23 GMT
Connection: keep-alive
Set-Cookie: PHPSESSID=NeknoCIkHzetzu9hvnwW; path=/; Secure; Expires=Tue, 05 Apr 2011 22:16:23 GMT
Content-Length: 16

Login Successful

 

No. 4 Expiration

When both the server and the user’s browser have an authenticated session token, there must be a way to force session tokens to both Invalidate and Expire. Otherwise, when session tokens remain active for extended periods of time, the attack surface of cookie-stealing techniques will increase.

To assure that session tokens expire, cookie values must first include some type of timed Expiration setting. Users who keep their authenticated sessions open for extended periods of time are then forced to log back into the application after they reach that established time limit. This lowers the chance that if a hacker steals a cookie, it would work immediately − compared to working six hours later. This problem creates high-risk situations especially when individuals use public computers. For example, say that a user accesses his banking information on a publicly accessible computer, and then fails to log out of the application; two hours later a second person using that same computer can gain access to the previous user’s banking information because the session token is still valid.

Secondly, applications that feature authenticated areas must also use Sign Out or Log Out links to force Invalidation of the session token value. This forced Invalidation allows users to terminate their own session. So, even if their cookies are stolen, the value will no longer work post-log out. Note, however, that removing cookies from only the browser during log out is insufficient to prevent an attack. Instead, the authenticated session on the server must also be killed in order to ensure that no requests using stolen session token values will be accepted.

A Note about SSL

I the application utilizes a Secure Socket Layer (e.g., HTTPS), then it is also a best practice to mark the session token value stored in a user’s cookies as “Secure.”

An Example of Setting the Secure Flag in Java Server Pages:

sessionToken.setSecure(true);

When the browser is parsing HTML in the source code, and sees a request for a new resource, the secure flag will ensure that the cookie storing the session token value is used only for requests sent via a Secure Socket Layer.

An Example in HTML Where the Browser Will Request an Image:

<img src=”http://www.example.com/images/image_01.jpg” id=”img1″ />

Because requests such as the one above are sent over an unencrypted transmission (http://) − rather than as a secure, encrypted (https://) transmission − the cookie with the secure flag is omitted from the request for the resource. Thus, any attacker performing a “man-in-the-middle attack” who sees a token sent over a plain text transmission (http) can use that token to steal a user’s account and attempt to access sensitive information. This method of attack is especially true in cases where separate host names are used only for hosting resources such as images, JavaScript, and CSS files.

But! Once a token is flagged as Secure, the browser will detect any token that’s sent over HTTP rather than HTTPS, and then omit any cookie containing a sensitive value.