I need to clear a concept.
I'm tracking unauthenticated users in my Django social networking web-app via setting a temp_id that's set in the request.session dictionary as soon as a new user hits the web-app's landing page. The code is is simply:
temp_id = request.session.get('temp_id',None)
if not temp_id:
request.session['temp_id'] = get_temp_id()
So far so good.
Apart from saving a temp_id in request.session, another technique I could have used is setting a browser cookie explicitly for unauthenticated users like so:
if not request.session.exists(request.session.session_key):
request.session.create()
The concept I'd like to clarify is are these approaches equivalent?
I feel they are. My reasoning is: if a browser cookie is just a reference to a Session stored in the DB, then if cookies were turned off, matching a Session for that user would be impossible. So regardless of whichever approach I take, I'll be relying on the browser's ability to store a cookie.
Or in other words, both methods of allotting a temp_id to an unauthenticated user are, under the hood, quite similar. The only difference is that browser cookies are less secure than session variables (over HTTPS).
Can someone point out whether this line of thinking is correct? Or is my approach wrong? I'm essentially trying to ascertain which approach to take for reliably tracking unauthenticated users once they hit my app's landing page and move about.
Related
Although there are many posts about this topic (or closely related) on SO, I did not find what I am looking for.
As the title suggests I am using Django Rest Framework as a backend, and React as a frontend.
Now I implemented token authentication, and it works perfeclty. The only problem is that the token is stored in React's state, and if the user refreshes the page, he is no longer logged in (the token is lost).
So, now I want to switch to session authentication, since the problem is solved then. But that will require me to do some research, and before I go there I'd like to know if that is the best choice.
My question:
Do I need to use session authentication to have users stay logged in, even when the React's state changes. Or can I also achieve the same thing with token authentication (in a safe and responsible way?)
I figure I can save the token in a cookie, but that doesn't seem safe to me.
EDIT:
Later I realized, why not just store the token in a session?
SessionAuthentication would be the most straightforward way to achieve what you want. The configuration is described at http://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme This will set a session id in a cookie that is handled by the browser.
Alternatively you can store a token in the browser's cookie but that is vulnerable to XSS attacks and other javascript attacks. For more security you can store the token in an HttpOnly cookie. The cookie would be persisted across tab/window closes by the browser.
Also to clarify cookie handling is built into most browsers. Your react state is in userland and lives in a different memoryspace than cookie storage.
More info:
Ask HN: Cookies vs. JWT vs. OAuth
https://developer.okta.com/blog/2017/08/17/why-jwts-suck-as-session-tokens
http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
I'm working on legal portion of my site, Privacy Policy in particular. I've done the research and found that nearly all the answers to my question (below), is generalized.
Question: Do cookies "collect" data from user browsers, or do cookies "request" then receive data from user browsers?
This seems to be a very important distinction. Do I put into my privacy policy that my site "collects" data from my users or do I "request" data from my users.
My understanding of the core functionality is that cookies request data of user browser or browser activity. Users control how their browser will respond (or handle cookies) in their browser settings. If users have the ultimate control of handling "responses" to cookies is it proper for website privacy policies to state that they use cookies to collect browser data? Isn't it more accurate to state something like: "We use cookies to request data from your browser. Depending on you have your settings, your response to our request my impact your experience." Or something along those lines.
For years the way I understood the phrase "cookies collect browser data" is that we (websites) force code (the cookie), onto your browser that opens a siv for all your activity to flow back to us. But this isn't the case at all. Cookies actually make a "request" (i.e., asks) for the user's permission first, and depending on how the user has set up their browser settings, the cookie request is honored or denied.
I'm trying to stay away from the term "collect" as a general matter. I think it's improperly used and leaves the wrong impression on users.
Has anyone else thought about this? Am I missing something?
Cookies are being stored to the system/computer - or you can say browser. Cookies are used for authentication, preferences, advertisements, performance and analytics, security purposes. Yes, we need to mention that in privacy policy or some organization also add separate cookie policy.
Following should be mentioned for cookies in policies for standard web applications:
The application may use and store cookies to your system/compute which can help better to know your preferences when you visit the website later. Cookies can also be used for authentication/session checks, advertising, performance, analytics and research and security purposes. //Remove whichever is not applied for your site.
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.
I was looking for the best practice to set/get login status and come across this one.
In the answer, Yuji suggested that setting or getting login status on a cookie is a terrible idea.
I am just curious why it is a terrible idea.
Can anyone advise?
The first reason that comes to mind is: cookies can't be trusted.
Now, Django does actually provide a system which stores user data in the cookie... cookie-based sessions ...they are not the default but the option is provided. Take note of the warnings in the docs - the data in the cookie is "signed but not encrypted" - this means the user (and anyone with access to that cookie) can see the data saved in the cookie in plaintext, but if they try to alter the data the cookie will be seen as invalid.
(Note that all Django sessions use a cookie, but the other session types like database-backed sessions don't store the data you associate with the user's session in the cookie itself, the cookie is just a token)
So, given that it is possible to safely store data in a cookie why do we say "don't do ever this" about the login state?
The main reason is because there is no point inventing your own half-baked login scheme when there is a standard, secure and well-thought-out authentication system provided with Django:
https://docs.djangoproject.com/en/dev/topics/auth/
If you need to know on the client-side if the user is logged in, the most common way is probably to pass a variable from the view into the template, eg request.user.is_authenticated and render some different HTML or write out a var into a javascript block.
In Javascript alone you could also check for the presence of the session cookie.
In addition to the answers given: Some people tend to use cookie blockers.
And if you clear your cookies while surfing, you can change your status.
I'm guessing Yes, but I'm not sure.
Both Authenticated Sessions and Anonymous Sessions would reference the stored sessions via the cookie.
########### edit: Clarify
It seems that sessions require some way of referencing for the stored session data.
This reference could be stored in a cookie OR added as a parameter in the URL.
I know this is taking you too literally, but it seemed appropriate to point out that HTTP is stateless and therefore does not have sessions. In order to maintain state, either the browser or the server have to persist the state information between requests. Traditionally, the server maintains the state, and by convention this is called a session, but it has nothing to do with HTTP as it is a workaround. Also, a session usually has a very specific connotation to it - namely that it is an individual visit to the site that will expire when it is no longer being used (some period of inactivity). It will also be different for the same user using different computers or browsers.
In order to achieve a server session, the server will generally set aside some information in memory or database to keep track of state and use a piece of identifying information to associate http requests with that state. This is usually a token. The browser needs to include information identifying the session with each http request. It doesn't matter how this happens, as long as the server and browser agree. It is most often a cookie, or url parameter as fallback, but as long as you set up the code right it could also be part of the url itself, part of a POST body, or even a non-standard http header.
The alternative that is becoming more and more popular is to maintain state in the browser and use purely ajax calls to the server. In this scenario, the server does not have to maintain any concept of session, and will simply return the data that is requested in a completely user-agnostic way. Some authentication may still be needed if the data is private, but a session token is not, and no state is kept on the server.
You can pass the session ID around as a query parameter (www.blah.com/index.php?SESSIONID=fADSF124323). But it has to be on every page. PHP has a option to enable this transparently. It is a huge mess. This is why cookies are preferred.
Not necessarily, some sites use a session ID value present in the URL that represents the session and this value gets appended to all links visited by the user.
We have to use it this way at work, since often mobile browsers don't accept cookies and this is the only way to remember a session.
Also there is HTTP-Authentication, not used often anymore today as the browser has to send username and password to the server unencrypted on every request.
HTTP-Auth just puts username and password in the header sent by your browser.
you can pretty much uniquely identify people by their browser plugins, fonts, etc.
https://panopticlick.eff.org/
When you're using SSL/TLS, then you could at least theoretically use the SSL session id to reference some state on the server.