In the Java Servlet API, what is done to ensure that someone's session id is not stolen?
For example, if I had an active session and someone somehow get a hold of my session id, could they use it?
Nothing prevents it. You get the session ID, you can take part in the session.
In the usual case of cookies this is not a risk in itself. The attacker should not be able to read a user's session cookie unless:
they've got man-in-the-middle capability, in which case you've got much worse problems than just session IDs;
you've left a cross-site-scripting hole, in which case you've got much worse problems than just session IDs;
you're vulnerable to DNS-rebinding/cross-domain-cooking attacks, in which case you should fix it by only allowing known-good Host: requests.
(Whilst you can try tying sessions to IP addresses, this risks breaking valid sessions due to eg round-robin proxies. IPs can be used as part of a wider strategy for detecting suspicious activity, but on the public internet it's not a good idea always to require each request in a session to come from the same IP.)
Unfortunately in Servlet there is another case, apart from cookies: jsessionid= parameters. Since they appear in the URL itself, that makes them much more leaky (eg via referrers and pasted links). And that's far from the only practical problem with parameter session IDs. They mess up navigation and wreck SEO.
In my opinion jsessionid= URLs are one of Servlet's worst early mistakes, a discredited cookie fallback strategy from yesteryear that shouldn't be used for anything. But certainly they shouldn't be allowed to grant access to any privileged data; consider using HTTP Basic Authentication instead if you need a fallback mechanism for browsers that don't support cookies.
In Servlet 3.0 you can disable jsessionid= URLs easily using <session-config> in the web.xml; unfortunately in previous versions you are left mucking around with filters if you want to properly disable the feature.
Yes, they could use it. Nothing is done to protect it unless you put all your traffic over SSL.
This is how Firesheep works, which recently got a lot of attention for making session stealing easy.
Yes, the Session ID gives someone access to the corresponding session.
You could store the IP used during login in the session and when the IP changes require the user to login again.
Additionally (not sure if that's done automatically though) you could do the same for the User Agent - not really increasing safety against malicious attacks though, just against dumb users giving away their sessionid accidentally if it's passed via GET and not a cookie.
Related
I'm using OpenID. How do I make it so that the user stays logged in for a long time even after closing the browser window?
How do I store and get access to the user's User object?
Basically, I guess I just don't really understand how sessions work in Java.
So you actually want like a "Remember me on this computer" option? This is actually unrelated to OpenID part. Here's a language-agnostic way how you can do it:
First create a DB table with at least cookie_id and user_id columns. If necessary also add a cookie_ttl and ip_lock. The column names speaks for itself I guess.
On first-time login (if necessary only with the "Remember me" option checked), generate a long, unique, hard-to-guess key (which is in no way related to the user) which represents the cookie_id and store this in the DB along with the user_id. Store the cookie_id as cookie value of a cookie with known cookie name, e.g. remember. Give the cookie a long lifetime, e.g. one year.
On every request, check if the user is logged in. If not, then check the cookie value cookie_id associated with the cookie name remember. If it is there and it is valid according the DB, then automagically login the user associated with the user_id and postpone the cookie age again and if any, also the cookie_ttl in DB.
In Java/JSP/Servlet terms, make use of HttpServletResponse#addCookie() to add a cookie and HttpServletRequest#getCookies() to get cookies. You can do all the first-time checking in a Filter which listens on the desired recources, e.g. /* or maybe a bit more restricted.
With regard to sessions, you don't need it here. It has a shorter lifetime than you need. Only use it to put the logged-in user or the "found" user when it has a valid remember cookie. This way the Filter can just check its presence in the session and then don't need to check the cookies everytime.
It's after all fairly straight forward. Good luck.
See also:
How to implement "Stay Logged In" when user login in to the web application
How do servlets work? Instantiation, sessions, shared variables and multithreading
Well, the original reason I chose OpenID was so someone else could handle as much of the implementation and security of authentication for me.
After looking into OpenID more, it appears there is something called an "Immediate Request" (http://openid.net/specs/openid-authentication-2_0.html#anchor28).
When requesting authentication, the Relying Party MAY request that the OP not interact with the end user. In this case the OP MUST respond immediately with either an assertion that authentication is successful, or a response indicating that the request cannot be completed without further user interaction.
Because of this I think I could just store the user's openID url in the cookie, and use an immediate request to see if the user is authenticated or not. This way I don't have to do anything with my database, or implement any logic for preventing session hijacking of the long-lived cookie.
This method of doing it seems to be the way OpenID suggests to do it with their Relying Party Best Practices document.
Okay. What I want to do is be able to, when I update a user, invalidate any session that they currently have in order to force a refresh of credentials. I don't care about being able to directly access the session-specific user data. Ideally, I would also be able to restrict users to one session by a similar manner.
What I tried doing is creating a HashMap using the username as key and HttpSession as the value (my actual setup is a little more involved, but after repeated seemingly inexplicable failures, I boiled it down to this simple test). However, whenever I attempt to tell the retrieved HttpSession to invalidate, it seems to be invalidating the current [admin] session. Is HttpSession inextricably bound to the current request?
Or is there an entirely different way to deal with this?
If it happens to matter, I'm using Jetty 6.1.26.
There's no straight forward way. The easiest way I can think of is to keep a flag on the database (or a cahche) and check it's validity on each request.
Or you can implement a HTTP Session listener and keep a HashMap of user sessions that can be accessed and invalidated.
I haven't tried any of these out so I don't know of any performance issues. But it should be acceptable for most applications.
Well, as far as I can tell, there's no way around it. Using a request-scoped bean didn't work as I expected (although it did give me good insights into how Spring operates, intercepting field accesses). I ended up using a dirty flag on my SessionHandler (a session-scoped bean) with a very high-priority aspect checking and, if necessary, calling invalidate() on the session in the user's next request. I still ended up having all my SessionHandlers register with a SessionManager, and a #PreDestroy method to unregister them in order to avoid a bunch of null entries in the map.
I am trying to learn more about JAVA web development. I am mainly focused on trying to understand how data that a user enters, maybe through the course of filling out a multipage form, is managed as the user moves from page to page.
From what I have gathered, you can store data within the session on the server side. I am also learning about cookies which are stored within the browser. Is there a general rule that is used to determine what data should be stored in a cookie vs. when you should store data in a session (session.setAttribute), or are these completely different concepts?
Thanks
The basics of session/cookies are like this.
A session is typically a way for a server to store data about a user. This can be done in a variety of ways from memory, file to database. This session can be used by you store pretty much anything you need to have as the user bounces around your site. It is assigned an ID (the session ID) which you don't usually need to worry about too much. In most web languages you can easily access the user session with some functions without dealing with IDs.
Now since the web is stateless - meaning there is really no way to know that user that visited page A is the same as the one that visited page B then we want to make sure that the user carries their session IDs with them. This can be done in a variety of ways but the most common one is through the use of a session cookie which is a special cookie automatically set by the server that is solely there for passing the session around. It can also be passed in the URL (I'm sure you've seen things like index.php?sessid=01223..) as well as headers and so on.
When most people talk about adding info to a cookie they are not talking about session cookies but about a custom cookie that you specifically set. The only reason that you would want to do that is if you needed to store info beyond the life of the session (which ends when the browser is closed). A good example of that is the "remember me" feature of many sites.
So use sessions unless you need to have something last a long time.
Yes. There are a few rules actually. For one, cookie data is sent by the browser on every request; session data is kept on the server (and not re-transmitted every request). However, usually the session id is used with a coookie. This enables the server to identify the client.
A customer has requested some security enhancements to our Java web application, including the following:
According to our security team good security practices state that
session id should be changed on every request to prevent session
hijacking.
I understand the importance of allocating a new session ID upon authentication (which we already do), but this request seems a bit extreme.
If reallocating on a per-request basis, it sounds like it's no longer a session ID, but rather a single-use request ID that might be used in conjunction with a session ID.
So, my question: is such a tactic really a common security practice? If so, could somebody point me to a good discussion on the topic, implementation tips, etc.?
It doesn't hurt, but it can be really complicated and really you only need to re-generate the session id when the security level changes. See also Session Hijacking - regenerate session ID on Security StackExchange.
Generating a new session ID for each request does not make any sense and it flies in the face of the concept of a session. However, including a request ID with all requests which will cause a state change (for example, form submission) is a very sensible idea.
The intent of a per/request ID is to prevent CSRF (Cross Site Request Forgery). See: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
I've been always trying to avoid using Sessions. I've used spring security or other ways of having user logged in the application, which is I suppose the major use case for using Sessions.
But what are the other use cases ? Could you please make a list of those most important ones ? How come that I've been able to develop even complicated applications without using Sessions?
Is it because I'm using spring-mvc and using Sessions is practically not needed except the login stuff ?
EDIT: Guys this question was asking for use cases... Most of the answers explains what are sessions for. If we summarize some usecases, we can say for sure, when to use database or sessions for maintaining conversation state...
Don't you remember any concrete scenarios you needed sessions for? For past years :)
for instance some conversational state may become persistent after some point / event. In this case I'm using database from the beginning.
I think you can do anything you want without storing anything on a sessions.
I usually use the sessions to avoid having to pass state between the client and server (used id as an example) and when I don't want to send sensitive information to the client (even in encrypted form) as it might be a security problem.
Other ways of avoiding using the session are:
store some state on a database, e.g. shopping carts, instead of in the session, even if the cart is discarded after a certain amount of time.
store state in cookies e.g. for user customization
One use case when it's really useful to use the session is for conversations, although usually frameworks manage that behind scenes, and store the conversation in the session.
edit
Converstions (in my understanding) are something like wizards, in which you complete several forms in different pages and at the end you perform the action. e.g. in a checkout process, the user enters his name, shipping address and credit card details in different pages, but you want to submit the order just at the end, without storing any intermediate state in your DB.
By sensitive information I mean, imagine in the previous example, once the user sent his credit card details, you shouldn't return that information in any format (even encrypted) to the user. I know it's a bit paranoid, but that's security :).
In the ecommerce system i'm working on, there is an external system at the back-end which stores users' saved shipping and billing addresses. Our web app talks to it by making web service calls to retrieve those addresses. When we get the addresses, we store them in the session. That way, we only have to call the service once, when the user firsts looks at their addresses, and not every time we serve a page which needs address information. We have a time-to-live on the addresses, so if the addresses change (eg if the user telephones the customer service desk to change an address), we will eventually pick up the fresh ones.
It would be possible to store the addresses in our database, rather than in the session. But why would we? It's transient information which is already stored permanently somewhere else. The session is the ideal place for it.
Well in one sense your question is deep (what's SPECIAL about a session is worth knowing) and in another sense it's shallow (what can't I do if I don't use them turns out to be a somewhat odd question)
In the end a Session is merely (or could be) a ConcurrentHashMap (in fact it usually isn't that threadsafe) with a a key of unique session id passing as the cookie. You know why it's useful, but to answer you for use cases
clustering (this is how state gets distributed across nodes)
caching general state of the user and their objects (as opposed to reloading from db each time)
built in methods for sessionlisteners to watch when someone is timed out, or attributes change.
= used for by a lot of localization utilities
Can you do all this with a database or your own hashmap implementation/filter? Of course, there's nothing magical about Sessions. They are merely a convenient standard for having some objects follow a logged in user and be tied to the lifetime of that user's use of the application.
Why do you use Servlets? You could also implement your own socket level standard? The answer to that is using standard apis/implementations provides convenience and other libraries build upon them.
The cons are
you are reinventing the wheel and some code that has been time tested
you won't be able to use a lot of built in facilities for monitoring/managing/clustering/localizing etc.
Sessions are one way of maintaining conversational state across multiple requests (e.g. multiple stateless HTTP requests.)
There are other ways of implementing conversational state, for example, storing an authentication token or some suitable conversation id as a cookie and maintaining a store of conversation id to session state. (In essence, duplicating what the app server is doing when it provides sessions.)
That you haven't needed to use sessions means that your application either doesn't need conversational state or you've implemented it in a different way. For example, perhaps your application uses an authentication token (say a cookie) and persists all state changes to the database. With that kind of arrangement, there is no need for a conversation state.
Hi you can take an example of shopping cart because since Http is stateless protocol it does not maintain the status of the user who sends the request.
For e.g.
If one user sends a request to buy camera from say eBay and after some minutes another user sends a request to buy laptop.
But since http is stateless protocol so server is not able to separate the request send by the users and may it happen that the bill of the laptop may be given to first user.
So through session we can maintain a particular entity over the server side for a particular user.