What are the risks of storing a user password in a Cookie, when the connection is via https? - cookies

A Note
I have a very good understanding of sessions and the theory of secure web-based authentication, etc., so please don't start with the basics, or give ambiguous answers. I am not looking for Best Practices, because I am aware of them. I am looking for the real risks behind them, that make the Best Practices what they are.
I have read, and agree with the principals that nothing more than a Session identifier should be stored in a Cookie at any given time.
The Story
However... I've inherited a rusty old app that stores the Username, Password, and an additional ID, in a Cookie, which is checked throughout the site as verification/authorization.
This site is always (can only be) accessed via HTTPS, and depending on your stance, is a "low-risk" website.
The application, in its current state, cannot be re-written in such a way as to handle Sessions - to properly implement such a thing would require, essentially, re-writing the entire application.
The Question
When suggesting to the-powers-that-be that storing their user's IDs/Passwords in plaintext, in a Cookie, is an extremely bad idea, what real risks are involved, considering the connection is always initiated and manipulated via HTTPS?
For example: is the only obvious way to compromise this information via Physical Access to the machine containing the Cookie? What other real risks exist?

HTTPS just protects against a man-in-the-middle attack by encrypting the data that goes across the wire. The information would still be in plain text on the client. So anything on the client's computer can go through that cookie information and extract the pertinent information.

Some other risks include cross-site scripting attacks which can enable cookie theft and who knows what kind of browser vulnerabilities which can enable cookie theft.

A given browser's "cookie jar" might not be stored securely, i.e., an attacker might be able to read it without physical access to the machine, over a LAN, or from a distributed filesystem (e.g., if the machine's storing user homes on a storage server, to allow for roaming), or via an application running on the machine.

Some browsers keep cookies in a file that can be displayed on the computer. IE6 comes to mind.
It seems to me that cookies are not all that restricted to a single site. Lots of advertising uses cookies across multiple sites. If I go to NextTag and look for a Nikon D700 camera then
I see NextTag advertisements on slashdot.org. This is an example of a cross-site cookie. Most users use the same password all over the web so if you store the password to one site and make it even a little easy to get to then malicious folks will sooner or later get to it.
To summarize this would be a very very very bad idea. On sites that I work on we don't save users passwords at all. We convert them to a hash key and save the hash key. That way we can validate the user but if we loose the content then there is no exposure of passwords. And this is on the server side, not the browser side!

Most cookies are limited time credentials. For example, session identifiers that expire after a couple hours or are forgotten when the browser windows. Even if the attacker gains access to the session cookie, they are guaranteed neither continued access to the account nor the ability to prevent the original account holder from logging in. Preventing long term account compromise is one of the reasons users are asked for their old password before being allowed to enter a new one.
A cookie containing a username and password, if disclosed, is much longer lived. Also, many users share their passwords between websites. As others have pointed out, the cookie could easily be disclosed via Cross-Site Scripting.
Finally, is the cookie marked with the "Secure" flag? If its not, an active network attack can easily force the browser to disclose it, even if HTTPS is used to serve the entire site.

People here already mentioned the "man in the middle" attack. The thing is that even with https it is still possible. There are different ways to do this - some of them relay on physical access to the network some of them do not.
The bottom line here is that even with https it is still possible for somebody to insert itself between your app and the browser. Everything will be passed through and will look from the browser exactly the same EXCEPT the server certificate. The intruder will have to send his own instead of the real one.
The browser will detect that there are problems with the certificate - usually it will either be issued to a different dns name or, more likely it will not be verified.
And here is the problem: how this violation is presented to the end user and how end user will react. In older versions of IE all indication of the problem was a small broken lock icon on the right side of the status bar - something which many people would not even notice.
How much risk this introduces depends on what is the environment and who (how trainable) the users are

Two two main vulnerabilities are cross site scripting attacks and someone accessing the user's machine.
Have you thought about just storing a password hash in the cookie instead of the raw password? It would require some coding changes but not nearly as many as swapping out your entire authentication system.

Related

Can trojans copy cookies of my website?

My website saves username and MD5ed password of user in cookies for login purpose.
My question is, can trojans in users pc steal that cookie and use it in another pc? If can, what is safe solution for remembering users?
Of course they can.
You can mix user's IP into MD5, but it still doesn't protect user for 100% (since trojan can use user's IP as well as steal cookies).
As long as trojan uses the same computer there is no difference between user and trojan, hence protection is not theoretically possible.
A trojan can access any file stored on the infected PC, inluding cookies. What you can do to mitigate the risk is to store a unique ticket id instead of the hashed password in the cookie, and save some additional information on the server for that ticket on the server - browser version, operating system etc. and only accept the ticket if the metadata match, too. That said, it's still not perfectly safe that way; if your web service is really critical, you better ask for the password every single time. (But since a trojan probably also installs a keylogger, this still isn't enough to be really safe...)
Trojans can also record the keys pressed by the user on the keyboard, so it's not really something you should worry about, because you can't do anything about it. It's the user responsibility to protect against malware.
What you should worry about are man-in-the-middle attacks, the fact that MD5 is not secure and the fact that you should add salt to your hashes.
By the way, most websites use cookies not to store usernames and passwords, but ephemeral session IDs. These session IDs become invalid when the user clicks on the "log out" button.

How should I manage username/password session information?

I have a website (the basic gist of which is described in this question), and I want to have some way to store the username and some information about the user consistently while they use the site (ie, upload and download data).
Right now, given a successful login, I was returning the hash of the password as well as any associated information. Anytime a user tries something, their username, hash, and so forth must match what's in the database. If the user logs out, their local Sinatra session has all information flushed.
I realize that this is a very naive approach. Is there a better way to handle user session information? The wikipedia entry on cookies mentions that a session uid is used instead of this other information; what is the advantage of that approach? I suspect that this approach is also vulnerable to other attacks, but since I verify everything that's done as it's done, I'm not sure what attacks I'm leaving myself open to.
Also, if/when I implement ssl, will these transactions be 'automagically' encrypted, or will I need to do something else to make sure that the strings are protected, if they need to be?
This is actually a very complicated issue. Just to illustrate, you have the problem of account lock-out: If you lock out based on failed attempts, how easy is it for an attacker to DOS your website?
I'll list a few best-practices to get you started:
Store Passwords Salted and Hashed alongside the Username and UserId. (You should also store the salt next to the hash.)
Disallow frequent bad-password attempts. (More frequent than once every few seconds).
If attempts are failing for any given user or any given IP address (more than 3 times a minute) require some form of human-validation, like a CAPTCHA. This allows you to prevent total DOS attacks.
If implementing an auto-login system, use a token authentication system.
For token authentication systems, use a Secure random number generator, send the plain token to the users, but Salt and Hash the token at the database.
Use TLS/SSL if possible, but don't rely on their security once the data is off-the-wire.
If your website is built in asp.net then you can use dot net securities.. which is really very good. and you can also use principle classes in it to make it more secure..

Is there much of an anti-cookie movement anymore?

I'm not sure whether this belongs on StackOverflow or on ServerFault, so I've picked SO for as first go.
A number of years ago, there was a highly visible discussion about mis-use of HTTP cookies, leading to various cookie filtering proxys and eventually to active cookie filtering in browsers like Firefox and Opera. Even now, Google will admit that currently about 7% of end-users will reject their tracking cookies, which is quite a lot, actually.
I still vett all cookies that get set in my browser. I have for years. I personally do not know anyone else who does this, but it has given me a few interesting insights into web tracking. For instance, there are many many more sites using Google Analytics than there were even two years ago. And there are still sites (extremely few, fortunately) which malfunction hideously if you don't let them set cookies. But advertisers in particular are still setting cookies to track your way across the web.
So is there much of an anti-cookie movement anymore? Has anyone tried to take Google to task for setting so many with Analytics? Is anyone trying to vilify sites like Ebay and PayPal who use a dodgy cross-site cookie to let you login?
Or am I making too much of a stupidly small problem?
Nowadays, there are other ways to block these annoyances. Rick752's EasyList has the EasyPrivacy list, which blocks most of them with no work at all other than adding the subscription once to Adblock Plus. NoScript can (with a little configuration, mostly removing some misguided entries on the default whitelist) easily block the ones which depend on JavaScript.
That said, I set up my browser to empty all the cookies on logout. Then they can track you only for the duration of a session, which will be short unless you tend to keep your browser open for a long time (or use the session save/restore all the time).
If you use Flash, know that it also has a kind of cookies, and the interface to manage them is most probably poorer than your browser's.
There's always people who misunsderstand cookies - on both sides. Ultimatey, it's up to the browsers to properly identify the sites for cookies. As long as the site's being set properly and the browser's respecting that, it's just not much of a problem. I think thta, with the increased use of web toolkits that take care of the programmatic details (and better, slightly more security-conscious browsers), it's not much of an issue now for end-users.
Beyond that, the proliferation of DHTML and XML-based partial-page-loading mechanisms (as well as database-backends and similar), the need to track session between stateless pages is reduced now. Your web app can very easily keep state without the need for cookies, and that may well have partially been driven by the number of [generally misinformed] end-users who blocked cookies all together.
In shorter words: "IMHO, no".
I gave up both as user and developer.
As a user the convenience of staying logged into sites is just too tempting, the pain of some sites not working too annoying. And I'm not that sensitive about my privacy, so I stopped caring and let all cookies through.
As a developer I always try to be as RESTful as possible, but I don't know any decent way of handling authentication without cookies. HTTP Basic Auth is just too broken, I can't assume HTTPS all the time and mangling URLs is painful and inelegant. What's left is form-based authentication with cookies. So my applications have one auth cookie -- I don't need any more than that, but that by itself requires the user to have cookies on if they want to authenticate themselves. Maybe OpenID and other federated identity services might fix that one day, but at the moment I can't rely on any of these yet.
My biggest annoyance with cookies is that I want to block Analytics cookies but at the same time I need to login to analytics to manage some customer sites. As far as I can tell they are the same cookie (in fact it may be the same cookie across all google services).
I really don't trust the Google cookie. They were apparently one of the first large companies to set cookie expiration to 2038 (the maximum) and their business model is almost entirely advertising based (targeted advertising at that). I suspect they know more about the day-to-day online activities and interests of people than any other government or organisation on the planet.
That's not to say it's all evil or anything but that really is a lot of trust to be given one entity. They may claim it's all anonymised but I'm pretty sure that claim would be hard to verify. At any rate there is no guarantee that this data won't be stolen, legally acquired or otherwise misused at some future point for other purposes.
It isn't impossible that one day this kind of profiling could be used to target people for more serious things than ads. How hard would it be for some future Hitler to establish the IP addresses, bank accounts, schools, employers, club memberships etc of some arbitary class of person for incarceration or worse?
So my answer is that this is not a small problem and history has already taught us many times over what can happen when you start classifying and tracking people. Cookies are not the only means but they are certainly a part of the problem and I recommend blocking them and clearing at every convenient opportunity.
I am also one of the hold-outs who doesn't automatically accept cookies. I do appreciate sites that need fewer, and I am more likely to return to those sites and allow cookies from them in the future.
That said, I do think that being vigilant about cookies is not (rationally) worth the effort. (In other words, I expect I will keep doing what I'm doing because it makes me feel better, even though I don't have evidence of commensurate tangible benefit.)
Every now and again I clear all my cookies. It's a pain as I then have to login to sites again (or set preferences) but this is also a good test as to whether either me or my browser can remember the login details..

Repeated cookie query or Storing in viewstate? Which is the better practice?

I have a internal website that users log into. This data is saved as a cookie. From there the users go on their merry way. Every so often the application(s) will query the authentication record to determine what permissions the user has.
My question is this: Is it more efficent to just query the cookie for the user data when it is needed or to save the user information in viewstate?
[Edit] As mentioned below, Session is also an option.
Viewstate is specific to the page they are viewing, so its gone once they go along thier merry way. Not a good way to persist data.
Your best bet is to use Forms Authentication, its built in to ASP.NET and you can also shove any user-specific information into the Forms Authentication Ticket's Value. You can get 4000 bytes in (after encrypting) there that should hold whatever you need. It will also take care of allowing and denying users access to pages on the site, and you can set it to expire whenever you need.
Storing in the session is a no-no because it scales VERY poorly (eats up resources on the server), and it can be annoying to users with multiple browser connections to the same server. It is sometimes unavoidable, but you should take great pains to avoid it if you can.
Personally, I prefer using a session to store things, although the other developers here seem to think that's a no-no.
There is one caveat: You may want to store the user's IP in the session and compare it to the user's current IP to help avoid session hijacking. Possibly someone else here has a better idea on how to prevent session hijacking.
You can use session data - that way you know that once you have stored it there, users can't fool around with it by changing the query string.
I would use the cookie method. Session is okay but gets disposed by asp.net on recompile, and you have to use a non session cookie if you want to persist it after session anyway. Also if you ever use a stateserver its essentially doing the same thing (stores session in the db). Session is like a quick and dirty fix, real men use cookies.

Concurrent User Sessions - Why Don't We See More Of It?

This is something of a rant, as well as a question.
There are some sites, like Facebook, where you would only want to be logged into one account at a time.
But everything from blogging sites to email always force you to logout before you can login to another account.
And I understand the security implications, and how it would make cookie-based sessions a little more complex, but why don't we see more of this?
Why would multiple users from a single client at once be a bad idea?
I think this is something that should be implemented by browsers by allowing multiple sessions, each using their own cookie/authentication/etc.
That would probably be the best solution, as it would seem to work for all sites, and require no updating for them, and, although I don't know much about it, it doesn't seem it would be terribly difficult to implement either.
The simple problem is most sessions are implemented via cookies, and there's pretty much no way to do it without cookies.
And the way cookies work, is they're bound to the domain/path, and all cookies tied to that domain are sent.
So if you permit logging in twice via 2 different cookies, the problem would be every successive page would send BOTH cookies, and the server seeing both has no idea which "user" you are acting as.
The only way around this is passing a "thread" identity around all links, ( that is, rewriting every site link on the fly to foo.bar?thread=2 or thread=1 to indicate which session to use for things ), and that is a complete nightmare, not to mention security implications.
The only real way to do it is via browser-sand boxing, the user tells the browser that a given tab and all offshoots use one cookie set, and the other tab and all offshoots use another.
In essence, its not a problem that can be solved by websites in a practical manner.
There's practically no good way to store this information without delegating the controls to how it works to browsers to implement, and for users to manually indicate when they want to fork into a new session.
Single Browser Solutions that should work today:
CookieSwap 0.5.1 Appears to permit "state toggles" of various cookie sets, It doesn't do whats needed to be able to just browse them magically, but its a partial solution. I can't test it myself because it hasn't been ported to FF3.1 yet.
"Why would multiple users from a single client at once be a bad idea?"
It is not a bad idea at all, but the use of HTTP forces us down this route.
Most client/server protocols are stateful - the client need authenticate only once during handshaking and then the session is represented by the socket connection. If you lose the connection, you lose the session and have to re authenticate. It is then trivial to write applications that allow multiple sessions (as the same or different users) in the one process.
HTTP is stateless. The client needs to re-authenticate in some manner with every single request. Authentication information is usually stored in cookies so that the user does not have to be involved once the initial authentication has been done. Cookies, however, are global - not just global with in the process, but generally across instances/invocations of the application. Hence, you are stuck with a single session.
You would have thought that web-app designers would have looked at this massive limitation as a sign that HTTP just isn't the right protocol for client/server application development.
One implication of multiple logins is how to manage privileges. Say I have two accounts, one has a privilege to delete user accounts and my other account lacks this privilege.
If I can be logged into both of my accounts simultaneously, which takes precedence, do I have the union of privileges from both accounts, or only the intersection of privileges held by both accounts?
If I have the union of privileges, would I have the ability to combine privileges from these multiple accounts in ways that give me too much power? What does this imply for Sarbanes-Oxley compliance?
An equivalent issue is seen in SQL, with respect to "roles" which are groups of privileges. In standard SQL, a given account is permitted to adopt multiple roles, but only one at a time. This prevents you from exercising too much privilege.
Cookie state is anchored to the host header...
Use a different hostname or use its IP address directly to connect to the site. Depending on the site you may be able to setup a bunch of local host aliases to the site allowing you to be logged on more than once as each alias would have its own cookie state.
If the site redirects to itself to force a specific host header the aliasing won't work and you'll need to use multiple browsers.
Since you first wrote the question, IE 8 has been officially released and it has a built-in feature that does what you want. From the "File" menu, click on "New Session." This will open a new window that will not share session cookies with the original window, allowing you to be logged into the same site under different logins simultaneously.
http://blogs.msdn.com/ie/archive/2009/05/06/session-cookies-sessionstorage-and-ie8.aspx
You can do multiple sessions in Firefox by creating new profiles - run: firefox.exe -P which is where you can set up multiple profiles that will have different cookies - you can run multiple sessions of firefox at the same time by using firefox.exe -P "profileName" -no-remote . the no remote will only allow 1 window per session but will also allow multiple sessions at the same time.