Encrypting a cookie in Django - django

Starting a with Django 1.4, we now get free cryptographic signing if we use the cookie-based backend for session storage, which is great. However, what if I want to store potentially sensitive information in the session? Ideally, I would encrypt it as well.
Here is a real use case: I want to store a temporary token in the session that allows me to issues requests against another service (this token expires after an hour of inactivity). Without encryption, anyone could get this token and issue the requests themselves, which I'd like to avoid.
I realize I can just encrypt/decrypt myself when I put it into the session, but I was wondering if there was a way to do this automatically for the cookie-based session storage. Does anyone have any ideas?

You should inherit signed session store and make it use your versions of singing.dumps and signing.loads which will, for example, encrypt pickled string with any necesssary algo (and decrypt it before de-pickling).

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.

Using JWT claims vs. storing data about user in a plain text cookie

Our intranet system stores user data once the user logs in simply using a cookie (UserID, Name, Role..)
I was learning about JWT and tokens today and wondering is there any advantage to using that over the current way?
It seems like something might be insecure storing plain text in cookies but I also read that other web sites cannot see those cookies..
So is there any strong reason to use JWT tokens instead ?
A cookie can not be accesed by a different domain that the one which created it. This restriction is called "same-origin" policy and is a security measure to protect the local data of the site, but it does not mean that your cookie is conveniently secured
Since you are not validating the cookie content in server side, for example a user could change his UserId or Role to get access to unauthorized resources.
JWT can help you because thencontent is signed with a secret key. Any alteration to the content will break the digital signature and the server will reject the token.
An alternative is to use server session and store this data on server.
The drawback with respect to JWT is that it needs server storage.

How to secure "remember me" token in cookie without storing data in database?

I want to secure remember me token for my website. I have read many articles but all points to one thing that to map those two tokens in database. Is there any other way that can be used to secure the token without using database?
You could use public key cryptography to sign the information on the server and then ask the browser to store that information as a cookie. You never need to share the private key to any clients for that. When restoring the session based on the cookie, the server can then verify the signature.
You could also encrypt the contents of the cookie with the same or a different key. Then only the server is able to decrypt what is stored in the browser, therefore even sensitive data can be sent there.
The most popular algorithm is RSA, but you should check out ED25519 that seems to be independent of any surveillance companies and organizations.

tornadoweb: storing cookies in database and retrieving them

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.

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