Cookie and security in Java (GAE) - java

Now in my application cookies for users are generated in a certain format containing userID. I want my cookie to be generated randomly after every login so even if cookie were stolen once they would never be used forever by a hacker.
What is the best practice of handling cookies this way? How should I store/retrieve them(hashtable/datastore...)?
Thanks

I would recommend using the built in Java session objects HttpSession, which GAE/J has support for.
Look here for the docs on how to enable sessions on GAE.
You can set the session to expire after a certain time period, or you could store a number in it and verify the session externally.

You can try following parameters:
user id
time to live (milliseconds)
hash for:
user password
user id
remote IP or browser
time to live (exact same as before)
and maybe an predefined string or salt
Join it into one string (like 13413:1826271762:b026324c6904b2a9cb4b88d6d61c81d1) and store it into a cookie like USERID.
On every request you need:
check that specified time is valid (less than current)
load user from database, by specified ID
validate hash signature (against current remote IP/browser and current password)

I agree with Rick, the container designers have done the dirty work of verifying if the request is coming from the same user and you don't want to reinvent the wheel do you?
HttpSession session = request.getSession();
This will create a new session, if one doesn't already exists but if it does it will get you the existing session.
session.setAttribute('key', value);
value can be any Serializable POJO and key is a string.
You can retrieve the stored value within the scope of you application by following code.
Object value = (Object) session.getAttribute('key');
For more information on how to use sessions check Java spec for HttpSessions.

Related

User Account Creation: adding to database, retrieving and displaying

I am curious about how it works when a user is trying to create an account on a website. Does the website use a session or cookie or even MVC to create the account, store it in the database?
I am not sure if session is too much to use for user account creation which includes certain validations (e.g. password needs to be of a complexity). Or would a cookie be sufficient?
I have read the following post but am still not sure on how to go about it to be efficient in my coding.
Session or cookie confusion
Differences between cookies and sessions?
Note: I am using eclipse and Tomcat 8
you can do by :
1/ creating a jsp page (view) where you put a form for user
2/ creating a java class(model) where you put a method that connect to database and insert data (example NewAccount(String username,String password,...){...})
3/ create a servlet(controller) to get data (name , password ...) from the form and pass it to the model by calling a method

Does session.getAttribute(str) in Java get stored on the server of client?

I am reviewing some Java code where a logged in user object gets stored with the line:
session.setAttribute("user", myuser);
and later retreived using the line:
myuser = session.getAttribute("user");
This works as expected, with the session.getAttribute() being able to read the saved user. However, I am wondering if this will work if the site is behind a load balancer, and mutliple instances are spinning up and down.
Are session variables stored on the client?: in which case, I'd assume a session'ed user object would be accessible across all running instances.
Or does session.setAttribute() store the user object on the server?: in which case if a user logs in on one instance, then a few page requests later gets bumped to a different running instance, I assume the session'ed user object would not be accessible.
Could anyone shed any light on this? Where does session.setAttribute() store it's data?
This is how it usually works - after user login, server creates unique SESSION_ID and return it in cookies. Also server creates Session object to store session information (Like session start time, session last activity time, user name etc.). When next request from same user comes - it contains that SESSION_ID in cookies, so server can find appropriate Session object.

Play framework how do sessions and cookies work?

How does play validate a cookie?
I noticed that after I restarted the server I was still logged in even though I
don't presist any session data in the database.
I also noticed
that I could set the date on the server to be larger that the exipry
date of the cookie and still I was logged in.
I logged out
(saved the cookie to a text file) and the browser lost the cookie. Then I
recreated the cookie from the text file and I was logged in again.
The cookie looks like this:
PLAY_SESSION=e6443c88da7xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-userid%3A1
// My logout code
def logout() = Action {
Ok("").withNewSession
}
From the documentation
Discarding the whole session
There is special operation that discards the whole session:
Ok("Bye").withNewSession
You didn't specify how do you authenticate users, so I just guess, that you;re using simple sample which is... simple.
It uses user's id to identify the user, and check if signed session cookie wasn't manipulated, therefore if you'll recreate the cookie with proper signature it will be valid still.
You should create some area for session's keys on the server side ie. in DB or in memory cache (Which will be faster than DB). Its key should be randomly generated (and preferebly quite long) for each successful login action, and should also contain data for identifying user, expiration date etc. Next you should put this random sess_key to the Play's session instead email address of logged user or id of his row in DB, and after logout and/or expiration date it should be removed. In such case even if you'll loose the cookie after logout it will be impossible to login properly with non-esixting sess_key.
AFAIR standard memory cache will be purged at every restart of the application, to make sure that all sess_keys from DB will be removed as well you can use Global object and truncate the table in onStart(...) method.
I found the answer reading the documentation more carefully and combining different parts.
There is no technical timeout for the Session. It expires when the
user closes the web browser. If you need a functional timeout for a
specific application, just store a timestamp into the user Session and
use it however your application needs (e.g. for a maximum session
duration, maximum inactivity duration, etc.).
It’s important to understand that Session and Flash data are not
stored by the server but are added to each subsequent HTTP request,
using the cookie mechanism. This means that the data size is very
limited (up to 4 KB) and that you can only store string values.
So that was what i feared that if the cookie get lost anyone can log in to the server for all future.
What I have to do to secure this is to add a self-made timestamp authorization (save a timestamp in the cookie and validate sever side)

Share Current User Data Between Subdomains on Google App Engine for Java

I am Using Google App Engine for Java and I want to be able to share session data between subdomains:
www.myapp.com
user1.myapp.com
user2.myapp.com
The reason I need this is that I need to be able to detect if the user was logged in on www.myapp.com when trying to access user1.myapp.com. I want to do this to give them admin abilities on their own subdomains as well as allow them to seamlessly switch between subdomains without having to login again.
I am willing to share all cookie data between the subdomains and this is possible using Tomcat as seen here: Share session data between 2 subdomains
Is this possible with App Engine in Java?
Update 1
I got a good tip that I could share information using a cookie with the domain set to ".myapp.com". This allows me to set something like the "current_user" to "4" and have access to that on all subdomains. Then my server code can be responsible for checking cookies if the user does not have an active session.
This still doesn't allow me to get access to the original session (which seems like it might not be possible).
My concern now is security. Should I allow a user to be authenticated purely on the fact that the cookie ("current_user" == user_id)? This seems very un-secure and I certainly hope I'm missing something.
Shared cookie is most optimal way for your case. But you cannot use it to share a session on appengine. Except the case when you have a 3rd party service to store sessions, like Redis deployed to Cloud Instances.
You also need to add some authentication to your cookie. In cryptography there is a special thing called Message Authentication Code (MAC), or most usually HMAC.
Basically you need to store user id + hash of this id and a secret key (known to both servers, but not to the user). So each time you could check if user have provided valid id, like:
String cookie = "6168165_4aee8fb290d94bf4ba382dc01873b5a6";
String[] pair = cookie.split('_');
assert pair.length == 2
String id = pair[0];
String sign = pair[1];
assert DigestUtils.md5Hex(id + "_mysecretkey").equals(sign);
Take a look also at TokenBasedRememberMeServices from Spring Security, you can use it as an example.

Session management between thick client and server?

My application is a Eclipse Rich Client and I would like to add authentication and authorization features to. My Users and roles are stored in a database and my application also has a web based admin console which lets me manage users and roles. I am leveraging Spring security on this admin console.
So here's my requirement:
I would like my thick client to provide users with a login dialog box. The authentication would need to be performed on the server side (it could be a webservice) and the roles have to flow in to the thick client. I would also like to manage sessions on the server side, somehow.
I really can't think of any easy way to doing this. I know that if I were to use Spring Rich Client, it would integrate pretty well with Spring Security on the server side.
But, that is not an option for me at this point.
Please share your thoughts on how to acheive this. Appreciate your help.
Since you're leaning toward web services (it sounds like you are) I'd think about taking the user information from your rich client (I assume user ID and password), using WS-Security to send the encrypted info to a web service, and having the web service do the auth stuff. Also I'd think about the web service returning any info that you want to go back to the rich client about the user (first/last name, etc).
I developed a similar application recently using the Challenge-Response-authentication. Basically you have three methods in your webservice or on your server
getChallenge(username) : challenge
getSession(username, response) : key
getData(username, action?) : data
getChallenge returns a value (some random value or a timestamp for instance) that the client hashes with his/hers password and sends back to getSession. The server stores the username and the challenge in a map for instance.
In getSession the server calculates the same hash and compares against the response from the client. If correct, a session key is generated, stored, and sent to the client encrypted with the users password. Now every call to getData could encrypt the data with the session key, and since the client is already validated in getSession, s/he doesn't have to "login" again.
The good thing about this is that the password is never sent in plain text, and if someone is listening, since the password is hashed with a random value, the call to getSession will be hard to fake (by replaying a call for instance). Since the key from getSession is sent encrypted with the users password, a perpetrator would have to know the password to decipher it. And last, you only have to validate a user once, since the call to getData would encipher the data with the users session key and then wouldn't have to "care" anymore.
I've a similar requirement I think. In our case:
user provides username and password at login
check this against a USER table (password not in plain text btw)
if valid, we want a session to last, say, 20 minutes; we don't want to check username and password every time the thick client does a retrieve-data or store-data (we could do that, and in fact it wouldn't be the end of the world, but it's an extra DB op that's unnecessary)
In our case we have many privileges to consider, not just a boolean "has or has not got access". What I am thinking of doing is generating a globally unique session token/key (e.g. a java.util.UUID) that the thick client retains in a local ThickClientSession object of some sort.
Every time the thick client initiates an operation, e.g. calls getLatestDataFromServer(), this session key gets passed to the server.
The app server (e.g. a Java webapp running under Tomcat) is essentially stateless, except for the record of this session key. If I log in at 10am, then the app server records the session key as being valid until 10:20am. If I request data at 10:05am, the session key validity extends to 10:25am. The various privilege levels accompanying the session are held in state as well. This could be done via a simple Map collection keyed on the UUID.
As to how to make these calls: I recommend Spring HTTP Invoker. It's great. You don't need a full blown Spring Rich Client infrastructure, it can be very readily integrated into any Java client technology; I'm using Swing to do so for example. This can be combined with SSL for security purposes.
Anyway that's roughly how I plan to tackle it. Hope this is of some use!
Perhaps this will help you out:
http://prajapatinilesh.wordpress.com/2009/01/14/manually-set-php-session-timeout-php-session/
Notice especially this (for forcing garbage collection):
ini_set(’session.gc_maxlifetime’,30);
ini_set(’session.gc_probability’,1);
ini_set(’session.gc_divisor’,1);
There is also another variable called session.cookie_lifetime which you may have to alter as well.
IIRC, there are at least 2, possibly more, variables that you have to set. I can't remember for the life of me what they were, but I do remember there was more than 1.

Categories