CSRF approach of tomcat(apache-tomcat-6.0.32) not working fine on firefox 14.0.1 - firefox

I am working on Security scan(to avoid cross site forgery) with the CSRF approach of tomcat(apache-tomcat-6.0.32) but I am getting following issue with firefox:
1. Firefox is not supporting CSRF provided by tomcat in a proper way firefox creating multiple sessions.
2. Whenever any exception (like JSP exception) comes on page. Firefox redirects it to CSRFPreventionFilter and this filter creates new session.
3. Sometimes while traversing through application also CSRFPreventionFilter filter creates new session.

The creation of an HttpSession is by design: the CSRFPreventionFilter uses an HttpSession object to store the nonces used to protect your URLs.
CSRFPreventionFilter only calls HttpServletRequest.getSession(true) and never invalidates the session, so it shouldn't be creating any additional sessions (or switching a session).
Note that recent versions of Tomcat will change the session id when crossing an authentication boundary (i.e. when you enter your username and password). This is a mitigation against a different kind of attack: session fixation.

Related

Spring Security "Remember Me" cookie gets deleted on browser closed event

I've followed Spring Security's instructions and managed to authenticate my users using JDBC in a Spring Boot project with "Remember Me" feature enabled (and setAlwaysRemember(true)). The "Remember Me" cookie gets created in the client's browser and the Token gets inserted into the "presistent_logins" table without fail.
But here comes the dilemma, When the client closes the browser, the "Remember Me" cookie gets removed automatically, which somehow makes all my effort effectless.
what would be the point of having Remember Me feature, if the cookie which is an essential requirement, gets removed on every browser closed event. Therefore, the user has to do the login all over again.
Here is a picture that shows the remember me cookie has been created after a successful login.
Do I have to take some special measures to make sure that the cookie gets preserved in the browser?
Chrome >>
Firefox >>
It's not the browser who is clearing the remember-me cookie. It's your spring app which tells the browser to clear that cookie (by giving an old expiry time).
So why does spring do that?
Because internally spring is throwing BadCredentialsException. You should debug RememberMeAuthenticationProvider class to make sure why it's throwing that exception.
In my case, the remember-me secret key was different than the one I used in my PersistentTokenBasedRememberMeServices class.
So please debug your application to find out the root cause of it...
Finally had to use normal mode of Remember Me feature (not DB persistence mode) in order to have this working. :(
When I use DB to persist session information, upon closing the browser, the "remember-me" session vanishes somehow!

Prevent session from being replicated when JSESSIONID cookie copied

Background: I have a javaee webapp deployed on tomcat which uses form based authentication. When the web server receives a login request, it sends the request to a dedicated authentication service which validates user login (User id and password). After successful authentication user's session is maintained in the web server.
Problem: I have written a simple webpp source code here, to simulate the scenario. On successful login the current HttpSession instance is invalidated and new instance is created. For each request for a post login page, the session is validated. A new JSESSIONID cookie is set which is used to identify the user during the session until session is expired or user logs out. This cookie can easily viewed in browser's dev tools. If I copy the cookie and set this in a different browser via JavaScript (document.cookie="JSESSIONID=xyzz") and then try to access a post login page, the server identifies it as a valid request and session is validated successfully. The post login page is served without user being challenged for user Id and password.
POC: User opens chrome and enter the URL http://localhost:8080/mywebapp/ and logs in with admin and pass1234. On successful log in the home page http://localhost:8080/mywebapp/home is shown. Now the JSESSIONID cookie is copied and set in FireFox. User enters http://localhost:8080/mywebapp/home in Firefox and is shown the home page without being challenged for userId and password.
Question: How can this be prevented wherein same session is getting replicated over multiple browsers?
You can't prevent this specific case of simply copying the cookie from your own browser (or by copying the cookie value from a HTTP payload copypaste/screenshot posted by an ignorant somewhere on the Internet). You can at most prevent the cookie getting hijacked by XSS or man-in-middle attacks.
This all is elaborated in Wikipedia page on the subject Session Hijacking of which I snipped away irrelevant parts (either already enforced by Servlet API, or are simply not applicable here).
Prevention
Methods to prevent session hijacking include:
Encryption of the data traffic passed between the parties by using SSL/TLS; in particular the session key (though ideally all traffic for the entire session[11]). This technique is widely relied-upon by web-based banks and other e-commerce services, because it completely prevents sniffing-style attacks. However, it could still be possible to perform some other kind of session hijack. In response, scientists from the Radboud University Nijmegen proposed in 2013 a way to prevent session hijacking by correlating the application session with the SSL/TLS credentials[12]
(snip, not relevant)
(snip, not relevant)
Some services make secondary checks against the identity of the user. For example, a web server could check with each request made that the IP address of the user matched the one last used during that session. This does not prevent attacks by somebody who shares the same IP address, however, and could be frustrating for users whose IP address is liable to change during a browsing session.
Alternatively, some services will change the value of the cookie with each and every request. This dramatically reduces the window in which an attacker can operate and makes it easy to identify whether an attack has taken place, but can cause other technical problems (for example, two legitimate, closely timed requests from the same client can lead to a token check error on the server).
(snip, not relevant)
In other words:
Use HTTPS instead of HTTP to prevent man-in-middle attacks.
Add a checkbox "Lock my IP" to login form and reject requests from different IP associated with same session in a servlet filter. This only works on users who know themselves they have a fixed IP.
Change session cookie on every request. Interesting at first sight, but breaks when user has same website open in multiple browser tabs/windows in same "session".
Not mentioned, but make sure you don't have a XSS hole anywhere, else it's very easy stealing cookies.
Last but not least, I'd like to make clear that this problem is absolutely not specifically related to Servlet API and the JSESSIONID cookie. All other stateful server side languages/frameworks such as PHP (PHPSESSID) and ASP (ASPSESSIONID) also expose exactly the same security problem. The JSESSIONID was previously (decade ago orso) only a bit more in news because by default it was possible to pass the session identifier along in the URL (which was done to support HTTP session in clients who have cookies disabled). Trouble started when ignorant endusers copypasted the full URL with JSESSIONID inside to share links with others. Since Servlet 3.0 you can turn off JSESSIONID in URLs by enforcing a cookie-only policy.
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
How to prevent adding jsessionid at the end of redirected url
remove jsessionid in url rewrite in spring mvc
What you have stated is called session hijacking. There are many good answers on how to prevent it.
Using same Jsession ID to login into other machine
we can use Encryption or hide JSESSIONID using Browser control.
Thanks

Spring MVC SPRING_SECURITY_SAVED_REQUEST causes continuous invalid sessions

I have a Spring MVC App and I have an issue with invalidated sessions.
The app performs AJAX requests that are all authenticated/tied to a session (hold a JSESSIONID)
So here's what happens. Let's say I'm in the app authenticated with a session. If I go into Tomcat and invalidate that session, then the next time an HTTP request gets made, Spring forwards me to the login page. Once I login again, Spring authenticates me fine, but then a number of my AJAX requests get HTTP 403 errors, continuously.
If I go into the HTTP Headers of the requests that get the 403s, I notice they have 2 JSESSIONIDs, one of the authenticated session, the other one of a session that holds only this attribute:
SPRING_SECURITY_SAVED_REQUEST DefaultSavedRequest[<OLD URL>]
So these sessions are not authenticated sessions so they are causing Spring to return a 403.
The issue is that this persists until I kill the browser (on some mobile devices that doesn't even work, and I have to go into settings to clear the browser cache).
Any suggestions?
this is a big problem because it's happening when Sessions invalidate themselves because of TTL, and we're stuck with users who get booted out, log back in and still get 403s, forever, until they clear the cache.
One thing to note is that Spring Security invalidates the existing session when you login and creates a new one, copying the contents of the old one across. This is intended to create a new session identifier to avoid session fixation attacks. You can try disabling this feature to see if it is related to your problem. It sounds like these are the two sessions you are talking about.
However if there are two JSESSIONID headers in the request then it sounds like a problem on the client side. You should work out why your client is sending two values. Also, it sounds like there may be an issue with Tomcat on the server side if you are still able to read the contents of the previously invalidated session.
Also check that Tomcat isn't sending two JSESSIONID values in the login response. There was an issue ages ago where it was doing just that, but it's unlikely you are running such an old version of Tomcat.

Spring 3 MVC session is lost after external redirect

I have a Spring 3 MVC app and part of the app requires a redirect to a 3rd party payment site and that payment site redirects back to my app after it's done. The problem is that Spring seems to create a new session instead of using the old one and erases all the data previously stored in the session. This creates massive problems for my app and I'm wondering if there is a way to preserve the session after external redirect?
Also, cookie are enabled on my browser and I indeed verified that the jsessionid value in the cookie changes after the redirect, indicating a new session overwriting the old one.
Can you provide the following info:
After coming back from the 3rd party site, does your app use a different domain/sub domain from what it uses before redirecting to the 3rd party site?
Is there a possibility that your session timeout value is so low that the session expires by the time the user returns to your app?
Does your app use frames having onunload events that invalidate the session?

How to pass / copy the parameter in java springs 2.5.6 when we switch between https to http

In my code I am using spring direct login.
Once controller switches between https to http a new session is created, once new session is created, how do I pass/ copy the session attribute to new session Which was created by http?
Check the Spring Security FAQ. Basically, you can't copy the session attributes - all the session data from the previous is lost when you switch back to HTTP. Since the browser won't send the secure cookie, you have a new session and it's as if you hadn't logged in at all.
There are ways of working around this (see the FAQ for more details and search the web) but they are generally a bad idea. You should start in HTTPS and stay that way if security is important.

Resources