tornadoweb: storing cookies in database and retrieving them - cookies

I have two web applications different things, but authentication is done only by one (using python and tornado), id like to have the second application access the credential of the user transparently, currently I can read the cookie of a logged in user via the header: Access-Control-Allow-Credentials , so how would i access the cookie, so i can store it (mongodb/redis/anywhere-but-mysql), and retrieve it in the second app?
what I've tried:
self.set_secure_cookie('cookie_name') # works i can see the cookie in subsequent request headers
self.get_secure_cookie("cookie_name") # just after setting the cookie returns None
what I was thinking is to store the encrypted value and compare it later in the second application as and when needed, is this sensible? all that i need to do is to ensure the user is
logged in and they exist in out list of users as of the moment.

So you've managed to set a cookie by one of the servers and then retrieve it on the second? If so, great! That's the trickiest part (imho).
Now there are two ways to go.
Store data in the cookie
Tornado have, as you've noticed, support for secure cookies. This basically mean that you can store data in the cookie and sign it with a secret. If both you servers have the same secret they can verify that the cookie data is not altered and you have successfully distributed data between the two servers. This decentralised alternative is not suitable if you need to store much data in the session.
A shared DB (or an API that the other server can use)
If you go with this solution you just have to store a session key in the cookie. No need to use secure cookie since it's no data stored there. You simply generate a SSID, e.g. ssid = uuid.uuid4().hex, store that in a cookie called something like ssid and also add a record to the DB along with all session data you want to store. I really like Redis for this since you can set the expire on creation and don't have to worry about that anymore, it's pretty fast and the best thing is that there's a nice and easy async lib you can use that plays nice with tornado.

Related

How to protect web application from cookie stealing attack?

My web application's authentication mechanism currently is quite simple.
When a user logs in, the website sends back a session cookie which is stored (using localStorage) on the user's browser.
However, this cookie can too easily be stolen and used to replay the session from another machine. I notice that other sites, like Gmail for example, have much stronger mechanisms in place to ensure that just copying a cookie won't allow you access to that session.
What are these mechanisms and are there ways for small companies or single developers to use them as well?
We ran into a similar issue. How do you store client-side data securely?
We ended up going with HttpOnly cookie that contains a UUID and an additional copy of that UUID (stored in localStorage). Every request, the user has to send both the UUID and the cookie back to the server, and the server will verify that the UUID match. I think this is how OWASP's double submit cookie works.
Essentially, the attacker needs to access the cookie and localStorage.
Here are a few ideas:
Always use https - and https only cookies.
Save the cookie in a storage system (nosql/cache system/db) and set it a TTL(expiry).
Never save the cookie as received into the storage but add salt and hash it before you save or check it just like you would with a password.
Always clean up expired sessions from the store.
Save issuing IP and IP2Location area. So you can check if the IP changes.
Exclusive session, one user one session.
Session collision detected (another ip) kick user and for next login request 2 way authentication, for instance send an SMS to a registered phone number so he can enter it in the login.
Under no circumstances load untrusted libraries. Better yet host all the libraries you use on your own server/cdn.
Check to not have injection vulnerabilities. Things like profiles or generally things that post back to the user what he entered in one way or another must be heavily sanitized, as they are a prime vector of compromise. Same goes for data sent to the server via anything: cookies,get,post,headers everything you may or may not use from the client must be sanitized.
Should I mention SQLInjections?
Double session either using a url session or storing an encrypted session id in the local store are nice and all but they ultimately are useless as both are accessible for a malicious code that is already included in your site like say a library loaded from a domain that that has been highjacked in one way or another(dns poison, complomised server, proxies, interceptors etc...). The effort is valiant but ultimately futile.
There are a few other options that further increase the difficulty of fetching and effectively using a session. For instance You could reissue session id's very frequently say reissue a session id if it is older then 1 minute even if you keep the user logged in he gets a new session id so a possible attacker has just 1 minute to do something with a highjacked session id.
Even if you apply all of these there is no guarantee that your session won't be highjacked one way or the other, you just make it incredibly hard to do so to the point of being impractical, but make no mistake making it 100% secure will be impossible.
There are loads of other security features you need to consider at server level like execution isolation, data isolation etc. This is a very large discussion. Security is not something you apply to a system it must be how the system is built from ground up!
Make sure you're absolutely not vulnerable to XSS attacks. Everything below is useless if you are!
Apparently, you mix two things: LocalStorage and Cookies.
They are absolutely two different storage mechanisms:
Cookies are a string of data, that is sent with every single request sent to your server. Cookies are sent as HTTP headers and can be read using JavaScript if HttpOnly is not set.
LocalStorage, on the other hand, is a key/value storage mechanism that is offered by the browser. The data is stored there, locally on the browser, and it's not sent anywhere. The only way to access this is using JavaScript.
Now I will assume you use a token (maybe JWT?) to authenticate users.
If you store your token in LocalStorage, then just make sure when you send it along to your server, send it as an HTTP header, and you'll be all done, you won't be vulnerable to anything virtually. This kind of storage/authentication technique is very good for Single-page applications (VueJS, ReactJS, etc.)
However, if you use cookies to store the token, then there comes the problem: while token can not be stolen by other websites, it can be used by them. This is called Cross-Site Request Forgery. (CSRF)
This kind of an attack basically works by adding something like:
<img src="https://yourdomain.com/account/delete">
When your browser loads their page, it'll attempt to load the image, and it'll send the authentication cookie along, too, and eventually, it'll delete the user's account.
Now there is an awesome CSRF prevention cheat sheet that lists possible ways to get around that kind of attacks.
One really good way is to use Synchronizer token method. It basically works by generating a token server-side, and then adding it as a hidden field to a form you're trying to secure. Then when the form is submitted, you simply verify that token before applying changes. This technique works well for websites that use templating engines with simple forms. (not AJAX)
The HttpOnly flag adds more security to cookies, too.
You can use 2 Step Authentication via phone number or email. Steam is also a good example. Every time you log in from a new computer, either you'll have to mark it as a "Safe Computer" or verify using Phone Number/Email.

Saving play framework sessions in database?

In the play framework website they say:
The session is a hash of key/values, signed but not encrypted. That means that as long as your secret is safe, it is not possible for a third-party to forge sessions.
is it really safe?
Is it possible to store sessions in a database like mysql or postgresql?
In a nother word do i need to do that?
And if yes, is there a best practice guide one can get help from ?
In play, session is a cookie on the client side. Values are not encrypted, this significates that with a tool like firebug you can see the content of the session on the client side. So you must not put in your session sensible data like unencrypted password.
Session are signed. This significates that it is not possible to modify the cookie on the client side and send it to the server because play checks that the content is in sync with the signature.
As sessions are client object, I don't understand why you want to store them in your database. The usual use case is to put the identifier of the user in the session and retrieve all other needed data from the database with this identifier

Sessions in REST services

I'm developing small REST service which should support client session persistence. As you know because of REST we can't store any client data on the server, data must be stored on client side and client's request must be self-sufficient. So...how we can store client sessions? Searching over the internet I've found some methods how to realize this. For example: we send to the client encrypted token which contains client's id(nick...etc), like token = AES(id, secretKey); and then we're authorize user every request decrypting token on the server with secret key. Can anyone advise anything? Maybe there is another good ways to do same functionality. Which crypto algorithm will be preferable for this? Thanks.
You mentioned:
As you know because of REST we can't store any client data on the
server, data must be stored on client side and client's request must
be self-sufficient.
REST doesn't say you can't store client data on the server; it just says you shouldn't store application state there, which you can think of as "what this client is in the middle of trying to do".
If you are primarily trying to just have a concept of authenticated users, then a standard login cookie will work just fine and is not "unRESTful".
It all comes down to your answer to this question: why do you need a "session" concept in the first place?
If you need to ensure that the client passes a cookie representing a set of credentials, consider instead having the client pass them as HTTPS authentication headers with each request instead.
If you need some sticky routing rules to be followed (to make sure that the client's request gets sent to a particular server), consider using this opportunity to get rid of that architectural straightjacket as it is the quickest way to kill your chances of future scalability. Instead, make your server choice arbitrary.
If you absolutely must route to a specific node, try requiring that the client pass enough identification data that you can use it to hash or shard the client down a particular "swim lane". You could split things up based on their username, for example.

What is the difference between a cookie and a session in django?

I think they are same thing but my boss say that is not right. Can someone explain the difference?
A cookie is something that sits on the client's browser and is merely a reference to a Session which is, by default, stored in your database.
The cookie stores a random ID and doesn't store any data itself. The session uses the value in the cookie to determine which Session from the database belongs to the current browser.
This is very different from directly writing information on the cookie.
Example:
httpresponse.set_cookie('logged_in_status', 'True')
# terrible idea: this cookie data is editable and lives on your client's computer
request.session['logged_in_status'] = True
# good idea: this data is not accessible from outside. It's in your database.
A cookie is not a Django, or Python specific technology. A cookie is a way of storing a small bit of state in your client's browser. It's used to supplement (or hack around, depending on your point of view) HTTP, which is a stateless protocol. There are all sorts of limitations here, other domains cant read your cookies, you can only store a a few k of data (just how much depends on the browser!), etc, etc.
A cookie can be used to store a session key. A session is a collection of user state that's stored server side. The session key gets passed back to the server, which allows you to look up that session's state. Most web frameworks (not just Django) will have some sort of session concept built in. This lets you add server-side state to an HTTP conversation.
To complement 'Yuji 'Tomita' Tomita's answer'
with cookies You can set any information on client browser
not just id (session id),
cookies are limited (size limited to kb), less secure and less flexible compared to sessions.
django sessions are based on cookies, django uses a cookie to save session id on client
sessions are not limited to data size (because they are saved on db of server), more secure and more flexible.

Storing a session using cookies or http session variables for a scalable solution?

I have one web app which under the login process stores the userId in a http session variable(After confirmation of course!). I'm not using any session variables other than this one to retrieve information about the user. I don't know if this one is the most scalable solution for me yet. Do my server reserve any memory for this? Is it better to use cookies instead?
If you are using multiple application servers (now or in the future), I believe the http session variable is dependent to the server the user is on (correct me if I'm wrong), so in this case, you can find a "sticky session" solution that locks the user to a particular server (e.g. EC2's Load Balancers offer this: http://aws.amazon.com/about-aws/whats-new/2010/04/08/support-for-session-stickiness-in-elastic-load-balancing/ ).
I recommend using a cookie (assuming my logic above is right), but you should make sure you have some sort of security measure on that so users can't change their cookie and gain access to another user's account. For example, you could hash some string w/ a secret key and the user ID which you check server-side to confirm it has not been tampered with.