Maybe I'm an ignoramus, but what's wrong with storing your credit card number in a cookie, as long as it's encrypted? This is how session management is typically done, right? Your session information is stored encrypted in a cookie so that on subsequent page requests, the server still knows who you are, but the session information is encrypted and decrypted on the server, so that the client can't forge the session information.
If this technique is good enough to make sure that you still are who you said you were when you logged in, why is this not good enough for storing other sensitive information? And if it's not good enough for session management, then you're in deep trouble anyway, since someone else can now log in as you and funnel all your money into their Swiss bank account.
Edit: As it turns out, it seems that most cookie-based session data is only stored cryptographically signed, rather than encrypted. The reason for this seems to be that HMAC signing is up to 4X faster than encrypting with Blowfish.
The level of 'good enough' security for banking is higher than general web browsing. Even though a user input for their CC number would be encrypted in transmission, that encrypted value is not stored for a long period of time. A cookie, even if encrypted, would allow for a greater ease of access, in general, so now it may be possible for a malicious user who is targeting the site to possibly gain many encrypted values - which depending on the encryption algorithm could allow for finding a flaw.
For session management - that's not the only way to handle user information. Often the web server will store a unique hash value and temporarily store the users information on the server with the associated hash. Note: if you're not using sticky sessions on server connects or a distributed server side session object that users info will be lost on reconnect if they hit a different web head.
And no, it is not entirely good enough for session management, which is why when you're on amazon.com or other online sites and you go to your account you are prompted to reenter your password. It is another level of security, but nothing is perfect.
Amazon/ebay/etc would usually do this because they have unencrypted parts of their site you can be directed towards, or unencrypted services, which would expose the cookies in transmission for session information [although I'm pretty sure they've got secure cookies for some parts of their acct mgmt]. Online payment processing force https for cookies and for session management and sets server & client side session timeouts, expire the cookie to prevent any possible future session hijacking, as well as many other procedures to secure their online services. There's a lot to PCI compliance.
edit: as phil said, HMAC is good policy if you store information on users on the client side, but I wouldn't put anything more than user tracking or analytics info in there.
> Maybe I'm an ignoramus, but what's wrong with storing your credit card number in a cookie, as long as it's encrypted? This is how session management is typically done, right? Your session information is stored encrypted in a cookie so that on subsequent page requests, the server still knows who you are, but the session information is encrypted and decrypted on the server, so that the client can't forge the session information.
No, that's not how session tracking works. The server uses a cookie to assign you a temporary ID, and then creates a corresponding storage area "server side" which can contain data like credit card numbers.
> Rails 2 introduced a new default session storage, CookieStore. CookieStore saves the session hash directly in a cookie on the client-side. The server retrieves the session hash from the cookie and eliminates the need for a session id. That will greatly increase the speed of the application, but it is a controversial storage option and you have to think about the security implications of it:
It's plenty secure in the sense that you can't forge a session. It's not secure in the sense that the data is inaccessible if you know how to base64 decode a cookie.
If you're using cookie sessions, you should know better than to store sensitive information in the session.
But it is not even encrypted. And AFAIK most (sane) sites do not store you account information encrypted in the cookie, they store a session id. This session id is then used to find the relevant session information which is stored on the server.
Well for starters, it's common practice (e.g. in Rails' cookie store, but many others too) to leave the cookie contents as plaintext and just append a HMAC so that you know they haven't been tampered with.
> it's common practice (e.g. in Rails' cookie store, but many others too) to leave the cookie contents as plaintext and just append a HMAC so that you know they haven't been tampered with.
This approach seems strange to me. Why is this approach taken? Why not encrypt everything?
I only really know anything about writing server-side web code from using Play Framework, which provides a "session" object for storing information in the browser using the cookies mechanism. Everything in the session object is kept encrypted on the client in a cookie.
The most common use for the session information is to store a user ID and/or a session ID, but I believe it not uncommon to use this to store additional small bits of information if this will take some load off of your database and/or cache, and to help the server be more RESTful/stateless.
Edit: It turns out that I was not quite correct about Play. Like Rails, it seems to only sign the session cookie, rather than encrypting it. From looking at some benchmarks for the performance of HMAC vs Blowfish, it seems that signing with HMAC can be up to 4X faster than encrypting with Blowfish.
It is based on the observation that most apps only store the user ID and other non-sensitive data in the session. Storing the session in the cookie then brings many benefits. It does not require any server side session store maintenance, it is very fast and scalable because no database lookup is required. The fact that this store should not be used for storing sensitive information is well-documented in the Rails security guide. For storing sensitive information, one can use many of the alternative session stores available, such as the ActiveRecord session store which saves session data into the database.
We at Phusion have created an encrypted session store in the past (http://blog.phusion.nl/2010/04/13/announcing-encryptedcookie...). However we've found it to be of limited use (and indeed, it doesn't look like many people use it). If your data is sensitive then you're better off storing it on the server. If your data is not sensitive then encrypting it doesn't help you.
I dont know either why is this the default in rails.
In PHP you only have a session id in a cookie. When I first saw how it works in rails (ruby?) it blew my mind.
I don't want to think about how many rails user don't know this and send sensitive data to the client.
The advantage -- and it's often a big one -- is that you don't have to have a corresponding server component to translate session id to session state. The state is all in the client.
Edit: wouldn't have written this if I'd seen FooBarWidget's more detailed remarks first.
The session information is cryptographically signed, so you don't have to trust it! These stateless server frameworks are just using the client as a state cache.
The information is usually already publicly available : for examples the facebook graph api uses the same setup for some of their basic api methods (such as letting a site log you in through facebook) - base64 encoded json user data and an hmac signed with a private key + timestamp. Since the data is already publicly available (it's your facebook user id and other publicly available data), there's no need to use a more costly encryption algorithm. The hmac is there to confirm to the server who manages whichever associated online service that also created a facebook app you just gave access your profile to that this is good data, since they've got the secret on their end that the staff registered with on facebook. HMAC is fast.
No, it doesn't. No one should be using Blowfish for anything (except its key scheduler for bcrypt) and Blowfish is known to be slow as hell. A SHA-2 HMAC is basically identical in speed to AES-CTR. Sure, you want an HMAC on that, too, but whatever -- get a modern processor or an AES coprocessor. I guarantee this is not your performance bottleneck.
>The most common use for the session information is to store a user ID and/or a session ID, but I believe it not uncommon to use this to store additional small bits of information if this will take some load off of your database and/or cache, and to help the server be more RESTful/stateless.
Even if the cookies would be properly encrypted, it still violates PCI DSS mandatory requirements - you aren't supposed to store or send a full credit card number unless necessary for an actual transaction.
They could do without a (full) CC number there. Ergo, it's a violation.
It's simple defense in depth, and does reduce the risks - say, if the encryption you thought was secure really isn't, etc.
IANA security expert but I think session info is somewhat protected by the short TTL. The amount of time required to get at the session data should (hopefully) exceed its window of validity.
If this technique is good enough to make sure that you still are who you said you were when you logged in, why is this not good enough for storing other sensitive information? And if it's not good enough for session management, then you're in deep trouble anyway, since someone else can now log in as you and funnel all your money into their Swiss bank account.
Edit: As it turns out, it seems that most cookie-based session data is only stored cryptographically signed, rather than encrypted. The reason for this seems to be that HMAC signing is up to 4X faster than encrypting with Blowfish.