Tomcat disable session not working - session

I have several apps deployed in Tomcat 7, and use Keycloak to manage user login and logout of these apps. Logout does not work i.e., does not log the user out and redirect to Keycloak's login page. Then I found the JSESSIONID cookie is still present, once I deleted the JSESSIONID cookie, the logout link works as expected. So I tried to disable Tomcat's session by putting
<%# page session="false" %>
in the header of my apps' JSP pages. Unfortunately, this still does not seem to disable Tomcat's session, I still see JSESSIONID cookie present. I am wondering if anyone has a solution to this problem? I believe the presence of the Tomcat session interferes with the Keycloak's SSO session, and causes Keycloak logout to not work. This has to be a common problem Keycloak users encounter, Tomcat is so widely used for web apps.
Would appreciate any tips on how we should handle this!

I don't have specific experience with Keycloak, however, there's a principle that applies to most if not all Single-Sign-On (or external authentication) solutions:
SSO identifies a user and removes the burden of knowing passwords from typical applications. When a user signs in, an application server is often detached from the actual SSO system, thus it will need to cache the user once they're identified, just as if the user identified itself with a classic login.
On the logout side, you can either log out of the application itself (tomcat in this case) or you can log out of the SSO system (which seems to be what you're doing here). With the later approach, you're running into the problem of "Single Sign Out": Logging out of the SSO system should invalidate all sessions that once were initiated with the associated login. As I know it, the SSO system needs to keep track of all of the systems that have signed on through it and trigger an explicit logout there.
I can't tell you how to implement this in Keycloak, but hope that the general principle helps guiding you towards the solution:
The use or non-use of a session on Tomcat's side has nothing to do with the problem: You might have applications that legitimately store information in a session in addition to the signed in user - those applications should continue to work even if you're not comparing passwords in tomcat itself.
Edit, after your comment:
If this one page doesn't trigger the use of a session, any other code (e.g. the code that processes your login) still might trigger a session and then later delegate to the page that doesn't want to use a session.
I'd expect that you'll have to disable sessions in Tomcat's configuration e.g. through providing a custom "Manager" implementation. It looks like the default ones do not expect you to completely ignore sessions. As I've outlined above, I'd also expect sessions to be required even if you're not logging in through Tomcat itself.
Another way to avoid sessions (this is the indicator why I don't expect "no session" config to work) is to avoid calling any method on request/response that would trigger the automatic creation of a session. And it seems that you have such a method somewhere in your app.
(someone correct me if I'm wrong. This is mostly my educated expectation as I've never looked at this requirement)

Related

Is there a way to check the authenticity of the user, after changing the Session Cookie?

Steps to re-create the issue:
Login with Admin Credentials and copy the session cookie.
Open another browser, Login as another user, paste the session cookie of the admin. Refresh the page. Now, you'll be
logged in as Admin.
How to solve this issue? Any suggestions would be of great help.
Tried using the event subscriber to get the previous session before drupal loads the cookie session, but no luck with it.
This is not a problem, I mean, of course, Session Hijacking is a really big concern - but standard defences are fine.
These are the controls that I know are widely known/used:
Ensure HTTPS is used everywhere,
Only use a securely created random string for the cookie value,
Set the secure flag on all cookies. This will ensure that they are only sent over an SSL connection,
Change the session cookie on each new login attempt.
All of Drupal 8's cookies are secure by default.
The exception is BigPipe's no-JS cookie, see https://www.drupal.org/node/2678628 — but there are no security consequences there.
I know some very sensitive applications may also store - for each session - the following additional information:
SSL Session ID
HTTP User Agent
Remote IP Address
In my point of view, I wouldn't bother with checking the HTTP User Agent or the remote IP address. They don't add that much security and they will break legitimate use in certain scenarios. Checking the SSL session ID (SSL session binding) would be OK from a security perspective, but could be painful to implement, the other defences are fine.
If your concern is Cookie Theft via XSS, the best defence is to use standard methods to avoid XSS bugs in your web application. See OWASP for plenty excellent resources.
You may find a lot of best practices to write secure code for Drupal 8 here: https://www.drupal.org/docs/8/security/writing-secure-code-for-drupal-8
You may also find a pretty old discussion about this on Drupal here: https://www.drupal.org/project/drupal/issues/19845

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

Host name issue with WSFederated Authentication

I have configured Local STS with my web application (which is hosted in IIS 7 and has the host name as www.abc.com) and it can receive the claims from the STS and it can login. Now I have added another host name (www.xyz.com) to my web application. If user a login to a page in the application using www.abc.com/page1 and it redirects to local STS and it authenticates the user and adds the security token. Now if the user visits www.xyz.com/page2 it also redirects to the STS for authentication.
If a user either logged in www.abc.com or www.xyz.com they need to access the other domain page with out login. Is it possible? How do we achieve this?
In broad strokes, if you have two different relying parties, each needs to route the user to the IDP. If the IDP is configured for single sign on, the user will only notice the routing to the IDP the first time. On the second routing, (assuming same browser session and that the routing is within the lifetime supported by the IDP) the user will be authenticated without seeing a page at the IDP and being required to present credentials.
So, part of your answer hinges around what you mean by login: if you mean "experience a challenge and enter credentials" by log in, you should be able to enable this by simply ensuring that the IDP is configured for single sign on.
On the other hand, if by login you mean the redirect to the IDP, then you need to make sure the application is able to share state across the different page names. Note that usual management of state is via cookies, and note that a cookie for abc.com will not be returned to a web page named xyz.com. There are a number of clever ways to resolve this, although i am not aware of any simple application configuration solutions. One example is to have some part of both the abc.com page and the xyz.com page accessed by the url shared.com. State cookies can then be set by the shared.com transaction when logging into abc.com and read by the shared.com transaction when subsequently accessing xyz.com.
I've never had to implement such a cross domain cookie solution and have only had off-hand conversations with colleagues about it: we've always found the silent redirect of single sign on to meet our requirements. Careful research into the privacy impact of such a solution and the likelihood that such cookies might be blocked should be considered before development.

How do I properly secure a REST-like service using Spring Security based on cookies?

I read this article on using Spring Security to "secure" (password-protect) a REST-like service: http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/.
This solution is what I seem to want, however, I noticed that at the bottom of the article, the authentication process is based on a cookie. If you notice, after a user logs in, a cookie is sent back to the user, and the user keeps using this cookie on subsequent request to access the REST endpoints (see the curl commands).
My concern about this approach centers on security; meaning, what's to stop the user from sending this cookie to someone else for use or someone from copying this cookie and using the REST service without proper authentication?
Is there a way to set the cookie (or cookies) such that it is valid for only one user? For example, for only the IP that authenticated correctly? But even this is problematic, as multiple users may share one external IP address.
It looks like the code is just demonstrating how to maintain a session between requests, exactly as your browser would do, by storing the JSESSIONID cookie. So I think your question is really the same as "what's to stop a user from copying the session cookie from their browser and giving it to someone else?". Of course there is nothing to stop them doing that but why would they want to? The same argument applies to any kind of security token. There's nothing to stop them giving away their username and password either which would have the same effect.
In most cases a web service would be stateless, so it wouldn't use session cookies. But OAuth tokens and so on are just as sensitive, often more so since they usually have a longer life span.

Remember-Me with Spring Security, various questions

I'm using Spring Framework 3.0.5 and Spring Security 3.0.5 for developing a webapplication where users can log in and log out, using Remember-Me-Service, if they want to.
As I don't have pretty much experience, I wonder if it's working correctly. I use PersistentTokenApproach (with my own implementation, because I use Hibernate.) I can see the cookie is created on login and deleted on logout.
If I have an valid Remember-Me-Cookie and close the Browser, Im successfully logged in again when I open the browser again. So far, so good.
Now, I'd just like to know if those things I noticed are working as they are expected to or if I maybe did make a mistake.
1) When a user logs in without remember-me and the browser-tab is closed (not the browser itself), on reopening a new browser-tab he is still authenticated (he's using the same JSESSIONID). When closing the browser and reopening again, he isn't authenticated anymore. Regarding the security of a webapplication, is this a recommended ("normal") behaviour?
2) When remember-me used and the user is successfully authenticated (by login or later by cookie), there are no more checks on the cookie. that means, if meanwhile the user is online I'd delete the cookie from the database, the user would still be logged in, allowed to watch even the secured pages. I guess this happens because he was authenticated before and keeps using the same SESSIONID. When I close the browser and reopen it again, he isn't authenticated anymore.
3) When I dont own a cookie and open the main page, for every request I send (every picture, every file on the page) the server is checking for the rememberme-cookie. Is that correct?
Sorry for the newbie-questions, but I just want to make sure everything is working as it should. :-) Thanks in advance!
1) As far as tabs within a browser go, I am pretty sure they all share the same browser session. If you try using gmail or other web-based services you'll see the same behaviour when you close / open tabs. With older versions of IE (maybe version 6) separate instances had their own sessions, unless they were spawned from existing IE instances.
2) This sounds correct. Its not really ideal to hit the database on every request after they have been authenticated.
3) That is correct, as by default the spring security filters will be filtering on /* - and trying to look for authentication info. You can add excludes to your security config for resources you dont need to protect- ie
<http> <intercept-url pattern="/images/**" filters="none"/>

Resources