What would be good/scalable user session alternative in following scenario:
users don't have to have cookies enabled
URL query string restriction of 255 characters is imposed
lot of GET requests (no hidden form fields)
application runs on several servers (web farm)
some users connect over proxy (same IP)
users connect over HTTPS
50 000 concurrent users
If you can guarantee that the client always connects to the same web server, you can use the SSL ID as a simple session tracking mechanism. Some web servers expose this capability and automatically use it for session tracking when cookies aren't supported.
The only solution that will work no matter what is to include a session ID in the URL itself. Adding a parameter to the URL is the simplest way to do this, but the ID can be embedded anywhere in the URL, i.e. as part of the path. You would use this ID to fish information about the user out of a database.
You will run into the usual problems, of course, with ID spoofing and having the session database be a bottleneck.
First, IMHO, there is no good alternative to session. The question is how do you obtain it when cookies are disabled. The answer is using URL parameter. So, you have to append session id to each request (including links and forms). All other requirements are not really relevant. Make your logic stateless, so you do not have scalability problems: all requests should arrive to your logic via load ballancer, so you can add as many servers as you want.
Maybe URL Rewriting or some URI shortening mechanism like http://tinyurl.com or http://goo.gl so you can pass your session details well under 255 chars.
Note: Not recommending to use these services but the mechanism.
First of all, your requirements are very tight.
The only option I see is using an approach like this: http://code.google.com/p/seaside/
In short: your system will generate statless urls like
http://host/app/#123445568978
Then you will go on the db to get the session object.
50000 users doing what? Continuous drag-and-drop with position updates to the server or clicking a text link every 15 minutes? In the last case: move everything onto a single server with a lot of ram.
Related
I have a website under a domain called www.example.com.br. And my server is set to work with cookie session tracking mode.
getServletContext().getSessionCookieConfig().setDomain(".example.com.br");
getServletContext().getSessionCookieConfig().setPath("/");
But now I'm introducing an english version of the website under www.example.com, because for Google and SEO techniques it's better to have different domains instead of a subdomain.
I found a lot of questions in Stack Overflow about this, and I know it's impossible for a lot of security reasons.
But isn't there anyway to tell Tomcat to work with a cookie domain .example.com.br if the URL has .com.br and .example.com if the URL has .com? I don't need to share session information... ie: the user may have to login again if he changes the domain. I'm not worried about it. The problem is that no information on the .com version is been stored at all, because the cookie is set to .com.br version.
Isn't there any workaround for that?
It is user's browser that decides whether to send the cookie with the request or not. Web server (Tomcat, in your case) does not have any say in that decision. What you are asking for explicitly forbidden. For example, RFC2109 says:
A user agent should make every attempt to prevent the sharing of
session information between hosts that are in different domains.
The best recommendation I can make is to make your session management (login, logout, ...) work off a single domain, regardless of what domain user originally accessed.
I know following are the ways to maintain or session tracking in java but looking for a good one
URL rewritting
Hidden form fields
cookies
Session object like setAttribitute() and session.getAttribute()
If the client browser has blocked accepting and storing cookies then last 2 ways are not valid.In hidden form fields I need to pass the hidden values in each and every page inside form.So suppose If I am just using response.sendRedirect() Then hidden form field is of not use.The remaining is URL rewriting in which I will pass JsessionID in the URl.So My question by knowing the sessionID isnt the unauthorized persons can able to access the pages.
For example There are 3 pages login,register,send.So after login user can register and/or send.So if any one knows the sessionID cant he/she go direct to register/send page.If yes Please tell me how to prohibit this
As of Servlet 3.0 (Apache Tomcat 7 onwards) if you use SSL then you can configure your application to track sessions based on the SSL session ID. The downside is that everything has to be over SSL. The advantages are that the session is strongly tied to the SSL connection. Only the user that created the connection to the server that has the correct SSL session has access to the session. Even if an attacker knows the session ID, they can't access the session.
One word of caution, this form of session tracking is the least widely used so it may not have been as heavily tested as the more usual cookie and URL re-writing mechanisms.
Have a look at this link which outlines Best practices for using HTTP sessions
Including
javax.servlet.http.HttpSession.invalidate()
Use HTTPS
With standard solutions you can't.
You can add some measure of security by adding request originator IP address verification, but that's also fooled easily. (to clarify some here means very tiny itsy bitsy little bit of)
So the secure route is to not use URL Rewriting to maintain session in secure application.
However you may be able to get some security by keeping the JSessionID as a separate encrypted attribute that which will be decrypted by a middle-ware or a load balancing server sitting between the client and your application servers. This of course is just a thought, I haven't, fortunately ever had to try something like that out :-)
Session tracking & authentication are two diff things don't club them.
Understanding your requirement I see you want to secure the sessionid of the user.
Evasdroping: If someone is listing to the request & response in the middle he can take the sessionid and use it. The best way would be to use a SSL. This ensures no one is listening in the middle.
Sessionid stolen from Client side: Normally this should be taken care by the browser and OS. So your user is as secure as the system he has.
I am searching for a Java library (or a simple class) that is able to manage server sessions for any protocol. My application is not related in any way to HTTP. The sessions have to stay alive between different connections, just like HTTP cookies do.
I guess the way to go is:
client connects to server
client sends the login informations
server replies with a status and a session ID (a long string, just like JSESSIONID or PHPSESSID)
client sends requests to server (with existing or new TCP connections), always providing the session ID
client asks to logout
server deletes the session and invalidates the session ID
I'm just looking for something existing regarding the session management part, even if it's really easy to implement. Otherwise I guess a Map and a random string generator will do the job.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html#randomUUID%28%29
http://www.javapractices.com/topic/TopicAction.do?Id=56
randomUUID() method could be useful in java.util.UUID see above links. It guarantees the id is unique.
If you want to make your session data to be scaled across multiple nodes, you can even try out frameworks like hazelcast, infinispan etc. They also have a provision to generate unique id across nodes.
We need to design a secure web application. I would like to propose a session handling mechanism which does a challenge-response on every request, not only during login using a CRAM method.
The reason is to harden the web application against session hijacking (eg by CSRF) and replay or man-in-the-middle attacks.
Using a nonce is suggested in some places, but in our webapp it seems impractical, as asynchronous requests can go on, or the user could open new windows, hit the back button etc.
Idea: The client and the server have a shared secret (a previously established user password), every subsequent request does again a challenge/response based on that secret, e.g 'response = hash(challenge + hashedPassword)'. The server executes the request only if the response to the challenge matches. Much like during CRAM, but ongoing for every request.
The question: Is this a feasible idea? If so, it surely has been implemented or is even some standard? How would we use this in a java or php based webapp?
The question really comes down to what you want to achieve. If you want to fight CSRF-Attacks, a secret token in addition to the session key is your way to go. However, changing the token in every request will cause problems - not only will the back-button kill the session, but as one webpage usually contains a lot of asynchronously and parallel loaded data (images, css, javascript, etc.), your approach will not enable any additional data to be loaded afterwards, as each additional request will change the required token, thus killing the session.
You may get around this by embedding all resources into the page via BASE64 and other tricks, but that will seriously hinder your possibilities and may have compatibility issues with some browsers.
So, in the end, your approach will not add much security, but will most likely create a whole set of potential problems for your customers. I'd stick to one secret token per session in the URL to fight CSRF and concentrate on securing against other attacks like XSS and user-friendly security measures like two-factor authentication with a smartphone or something similar. After all, the user is the #1 attack vector nowadays.
Update (2012-06-14)
The token will not fight XSS-attacks, but it will defend against basic CSRF-attacks (e.g. by implanting a bogus url call in an image). I've actually had a situation at work today, where I needed to secure a get-request against user modification and worked up some code. The code may be also usable to secure static, session-timeout form- and link-tokens (right your problem).
The idea is to have a server-secret, which is used to generate a hash/AuthToken over data to secure. If a rogue javascript would try to change any of the given data, the AuthToken would not match. In my specific problem, I have one server authenticating a user and have to send his information over to a third party (username, mailaddress, name, etc.). This GET-Request might be easily changed by any user after authentication, so I have to authenticate the GET-Request-Parameters. By rerunning the AuthenticationToken-Process, the third party can compare the resulting AuthTokens, thus validating the incoming data. Without the shared secret, it is (near-to) impossible to forge the data.
On your problem: Having a static token on GET and POST-requests (or a dynamic one like the project of mine) will protect you against simple CSRF-attacks via e.g. links in forums, which a user has to click to get attacked. As the link will never contain the correct token, your webpage is secure. However, if an attacker manages to load a javascript into the webpage via XSS, you're screwed and no technique in the world will help against it, as the javascript can scan the whole DOM-tree of the page to find an capture any tokens whatsoever.
So, it comes down to this:
use tokens on GET and POST-requests to fight CSRF
secure your page against XSS-injections
I find the OWASP cheat sheets are a good resource for such design decisions:
CSRF Prevention Cheat Sheet
XSS Prevention Cheat Sheet
Your scheme sounds similar to the HTTP digest authentication without establishing any kind of session post authentication. Which is probably an improvement over HTTP Basic. And that is assuming both are over TLS!
I am not sure how feasible your scheme might be or how vulnerable to replay attacks or MITM it might be.
If it is an option you might consider the new <keygen> html5 tag which can help establish a two way TLS session. This would be the most secure option..
I have a case where non-interactive devices have to push data to a server periodically over HTTP. I am thinking of taking an auth token approach to verify the validity of requests from these devices.
First the device wakes up and initiates a ssl connection and submits its credentials to the server; the server verifies the credentials and generates a SHA based token, based on the credentials + some random input, and sends the token back to the device
This token must be present as a header in each http request that the device sends up. The server will use a servlet filter that looks for this header and filters out messages that don't have it.
There is no sensitive information transferred, I just want to make sure that the device talking to the server is a valid one, and not someone trying to mess around with invalid data. (Wannabe hackers, script kiddies etc..)
The token needs to be stored somewhere where multiple 'nodes' can verify that the request is valid - where do you recommend doing this ?
I can think of 3 approaches
1) Have a separate web service that maintains tokens and does the authentication ( I cringe on the performance overhead of this for each request)
2) Maintain a Set of authenticated token in the Session, and let the servlet container take care of it using the built in clustering support (Not sure if this is the most fool proof way )
3) Use a database to store the tokens and verify it (Considering Redis for this)
Also, I think this approach has a vulnerability of allowing man in the middle attacks, but since the client sends data only for a few minutes I am taking a chance, any better approaches would be welcome.
My opinion:
1) Have a separate web service that maintains tokens and does the authentication
If it's about performance and you have to maintain a lot of devices, I agree that this may become a performance bottleneck.
2) Maintain a Set of authenticated token in the Session, and let the servlet container take care of it using the built in clustering support.
Personal opinion: never rely on sessions in a systems integration scenario. Second, in clustered environments you have to replicate session state between members. Although the container takes care of this it will have impact on performance as well in case of in-memory replication.
3) Use a database to store the tokens and verify it (Considering Redis for this)
If a database is already in place, do it here
Alternative: Use a symmetric hashing approach. After the device authenticated itself return a one time token (digest) each server node can verify independently (based on certain criteria, e.g. a password). "Shared nothing".
BTW: no question, the transport has to be secured (TLS/SSL).
I think that the 1st solution will be the most scalable and flexible.
Try OpenAM with SAML. This is out-of-the-box solution. It has such a filter and can manage repository with such data. A more bulletproof solution could be based on WebSphere DataPower and SAML. If SAML is too complex you can use lightweight, custom solution, but IMHO the 1st idea will be the best.