I know that codeigniter stores it's sessions as a cookie, which, from reading around I understand to be somewhat insecure. So... I am planning to enable database storage for sessions, which I believe:
a) Is safer?
b) Allows you to store more data than the 4kb limit offered by cookies?
However on the flipside I guess this will be slower for the system to retrieve, for example, in my application I regularly want to query the session data to determine if a user is logged in.
Is is a good idea to store sessions in the database, or will this slow down my app considerably?
Any other ideas or suggestions regarding sessions and cookies would be most appreciated.
Well, that is true and false. CodeIgniter can be configured to store its data on a DB, but it can encrypt the cookies before storing them on the client. It also MD5's the cookies contents to ensure data integrity (basically if the Cookie's MD5 doesn't match correctly, then it is rejected). So while by default it is possible to edit the cookies, it is more than annoying to do so.
Personally, I generally prefer to store session level data in the $_SESSION and have modified my session object to allow me to do that. I also make the PHPSESSID variable a good deal more complicated.
As to your question, "Is it a good idea to store sessions in the database", well, that depends on how fast your database is and what your memory requirements are. It could slow things down or it could, conceivably, speed things up based on configurations et al.
Related
I would like to know if it is a good idea to sign cookies with hash to check it's integrity? First of all, I do realize that I should not store any sensitve data in cookies and use sessions instead. That's exactly what i do. But still I am feeling not comfortable with user being able to modify even not so important data. (I'm kind of security paranoic :) )
I came up with the following solution. Let's say we have cookies for:
PHPSESSID
site_lang
recently_viewed
Now whenever I update cookie value I recalculate hash for cookie with key of let's say cookie_hash and value of let's say md5(serialize($_COOKIE)+$secret)
the only thing that I am not using PHPSESSID for calculation and validating hash because it is not being managed by CookieManager class (my custom class) and might be refreshed with new session id and corrupt hash.
My concern is what if some third-party package sets it's own cookie bypassing my CookieManager of course. it will collapse hash. So is it a good idea at all?
MD5 is weak for this, and the scheme you proposed (hash(data||secret)) is flawed anyway. Cryptography is hard, please don't try to come up with your own. :)
What you may be looking for is invented already, it's called message authentication. Have a look at things like HMAC, which is one proper way to do something very similar.
In most cases, authenticating cookie values doesn't make sense in a web application and provides no additional security, but there are cases, when it does. Your examples above don't seem so. :) For example the session id is cryptographically random already, and the other two usually present no harm if changed by a user (but in very special cases, they probably may, though I can't come up with a reasonable example). If something matters and should not be changed by the client (user), that should probably be stored in a server-side session.
However, you may decide to store application state on the client in encrypted and/or authenticated cookies, one reason for that may be a stateless application on the server (see the default session management in Ruby on Rails for example), and in that case, something like your idea (but done correctly) is indeed the solution, but it has its own set of risks (as do server-side sessions).
Note that anytime you store state on the client, one threat that comes up besides secrecy and authenticity is replay. This affects your idea as well. Say it is a problem in your application if the user can change the last_viewed cookie, but you still don't want to put it in the session. You properly authenticate the cookie, maybe even encrypt it, the client has no access. But what if at some point, the user saves the cookie, and in a different session replays it? (Okay, your example tries to protect all cookies at once, which may make this a little bit more difficult, but you get the idea, replay is still a potential problem.)
So in short, you most probably don't need this, but if you do, then use proper message authentication (something like an authenticated encryption, or a proper MAC like HMAC).
I don't know how deep you digged in PHP and Webdevelopment, so please forgive me if the level of my answear is to low.
If you are paranoid you should read more about PHP, sessions, cookies, hashing algorithms and more.
For example:
PHP session handling
PHP session configuration
PHP session security
With this you can modify your sessions & your handling a little bit to serve your paranoia.
By the way you shouldn't use something like md5 in reference to make your web application more secure.
If i understand what you want to do, you want to write a hash of your serialized session array plus a secret/salt into the session to verify the integrity of the session and its data.
If this is your motivation, you really should rethink, at least in my opinion.
A session is just a file on your server (on the users system it's a database entry in a sqlite database of firefox or something else, but without the data you write to the cookie array, that data are just writen to the server) and the session ID is a file name/path to this data on the server, except your sessions are saved on a database.
So with your approach you would just save the value to verify the integrity of the data in the same data (on the server) you want to verify.
And where you want to save the secret?
I think it's a little bit useless.
Depending on your needs and the needs of your application you could search about the key word session TAN, you could set a additional cookie with a random value you save on the session to verify each other, you could save and check the IP (depending on the law of your country and the way your users connect), shorten the session lifetime and more.
You could also set ini directives like session.cookie_httponly (that's one i recommend if you don't want to access your session cookie by a script language like JavaScript) you can find on the links above and more.
Something is a matter of faith, something evident.
Digg in deeper and understand how the technology works under the hood and you can make your decision more easy by yourself.
Lately I have stumbled upon some articles that suggest using a cookie to store session data.
I liked the idea and extended my session storage by adding a CookieStorage class which works fine (note that per user I use a unique hash key for sigining and encrypting data)
However, there are a lot of other articles that suggest against storing sensitive data in a cookie, even though you encrypt and sign the value.
Personally, I find no reason why not do it especially when encrypting and signing the value with a different key for each user. The risk of the data being compromised is the same as with normal sessions, no? Not to mention that if you use SSL then the risk for hijacking is eleiminated.
What I see as a benefit with such an approach, if the session data are not large, is fewer IO operations on the server for opening/reading/writing session data, whether the storage is file, db, memory based
I would appreciate your feedback on the matter
Thanks
If you're using pure cookie storage with no server-side component at all, then the user is in control of the data. The only thing keeping him from it is your encryption/signing method; but that can be attacked. If you're not using encryption/signing keys specific to the user's session (i.e. you're not using a server-side session), then you're pretty much limited to a static secret. Someone could attack that offline, trying to brute force it. Once they did, they could spoof their entire session.
If you are using more secure one-time random secrets stored in a server-side session... you're already storing data in a server-side session! Why not keep it simple and store everything there? It would also reduce the bandwidth needs required to transfer all the cookies back and forth with every single request.
If you're doing this mainly to save I/O operations on the server: use a more efficient session store like a memcache based store.
Although nowadays session id transferred only via cookies, initially there was other ways, which are still supported and can be used.
Sometimes server needs to know or alter the session info.
That point from #CBroe on the cookie size.
I'm not concerned with browser compatibility.
I want to know if I move my state from PHP Controlled ( Server-Side) sessions to the JavaScript Controlled ( Client - Side ) HTML 5 local storage will I gain or loose security.
I think that I would gain security because now instead of having the user identifier residing in a cookie, which is usually a file, or sql database that is easily accessible...it is not inside some sort of internal browser storage. + b.c. it is a newer technology I would hope that more security was designed into it.
Do I gain or loose security by moving from PHP Sessions to JavaScript Local Storage. ( This is for things like user id, page_id, etc, the current state that remains after a reload and longer if needed ).
I have a JavaScript solution I want to replace my PHP Sessions with. That is why I ask. I don't care about browser compatibility.
Here is an informative site on Local Storage. But Security was not mentioned.
Both types of local storage (localStorage and Cookies) use some sort of identifier which is obviously stored on the client.
Both use a hash mechanism to secure it from altering to another user.
Local Storage is more secure then cookies ( see here ).
And obviously you have to write the session protocols if you want to move your user identifier from cookies to localStorage.
Both can be stolen to fake being another user. Though less likely with localStorage.
And to make robust you need a fingerprinting technique that will help with above problem.
I have a JavaScript solution I want to replace my PHP Sessions with.
No. Do not do it. Sessions are stored in the server side. The cookie that is sent out to the browser is typically an identifier for that record. Session stores user-specific data. Almost anything stored on the client side can be easily modified by the user. So if the user modifies the session to point to another user, the security would no longer hold.
LocalStorage is NOT for storing sessions. Stick with PHP sessions, or any other session mechanism that is implemented on the server side.
Update
But the same security flaw is present...a user can login as one
person...fiddle with the session_id of the Session and become someone
else...fiddling with a session_id...equates to fiddling with who you
appear to be to the server ?...this would be the same as fiddling with
an encrypted user_id in local_storage.
No. Suppose I figure out the algorithm you are encrypting with. And I know of another user say UserB. I encrpyted his username using that algorithm. If I somehow overwrite my localStorage with that encrypted string, I am him now. That is not much possible practically. Think of it as there are 100 users and 128 byte-string is the identifier. Are you sure you would be able to fiddle with it and modify it into another record which exists in the table of sessions?
Local storage is best suited for data that you want to cache on the client in a (more permanent) way then with the regular browser cache. The only way it's "more secure" is if you want to allow the user to work with data that's never sent to the server.
If you're worried about session hijacking, the preferred solution would be to use https/ssl and encrypt all traffic between you and the client. There's a general overview of the problem and solutions on wikipedia (we'd need more information to give you anything much more specific than that, though).
You wouldn't gain or lose security as in most browsers all data set by sites are stored in the same folder
How can I encrypt, and later decrypt, a cookie value in PHP? How secure will the encryption be?
There a variety of different ways to encrypt information in cookies and elsewhere. The strength of the encryption will vary by the method you choose to do the actual encryption. mycrypt is a good place to start. See this answer for an example of using mcrypt.
I don't recommend putting anything sensitive in a cookie, even if it is going to be encrypted. Way too tempting for someone to crack. Try sticking to sessions if you can.
I am in full agreement with the other answers: If the data is truly sensitive it should be stored server side in a session, not in a cookie.
As far as ways to encrypt cookie contents, the Suhosin PHP extension provides the ability to transparently encrypt all cookies. If you have the ability to install PHp extensions this may or may not be easier for you than writing your own encryption scheme.
If the cookie is encrypted securely (for example, with a server-stored secret that changes on a regular basis) I see no problem with storing useful data in the cookie. Why store it on the server? Make the client do some work for a change -- especially if it is preferences. Why should the server have to constantly store and retrieve data from a session file? What if you have hundreds of thousands of users pounding your site? Now you have to maintain hundreds of thousands of session files.
I can think of a reasonable use for this. Suppose you have a large server farm, you're going to have a bottleneck at the database and/or memcached server for handling session requests.. "is this user logged in?"
If you were to store the users session data as an encrypted value in the cookie, then you can prevent having to do quite a few read/writes and allow for an unlimited sized cookie store since there is 0 impact on your side other than being CPU bound for encryption/decryption of the cookie data.
Ruby on Rails by default does this - although it only signs the data and does not encrypt it. There is an alternative implementation which encrypts the data with its own key and signature so you the user is not able to see what data you store in their session.
I can not simply think of a situation where encrypting data in the cookie is useful. If you want to retain secret data about the user or his preferences, information, whatever, then store it on the server in files, in the session or in the database, but not in the client's computer.
On the other hand, if you creating an authentication, then you should use sessions instead of creating secret encrypted cookie values. Sessions weren't implemented for nothing, they are the way to go.
Is it slower to retrieve a user's cookie and get its value as a PHP variable, than it is to retrieve a session variable?
In general, you should not worry about the retrieval speed of a session variable or a cookie.
You should however be aware of the differences between them:
Sessions are stored on the server, which means clients do not have access to the information you store about them. Session data, being stored on your server, does not need to be transmitted in full with each page; clients just need to send an ID and the data is loaded from the server.
On the other hand, Cookies are stored on the client. They can be made durable for a long time and would allow you to work more smoothly when you have a cluster of web servers. However unlike Sessions, data stored in Cookies is transmitted in full with each page request.
No. In pure technical terms, it is likely the opposite, as there would be a bit of minor overhead to initializing a session.
Cookie data comes in as part of the HTTP request no matter what, and PHP reads it into $_COOKIE by default. So it's always going to be there. $_SESSION requires you to call session_start() at some point.
However, the performance difference between the two is going to be ridiculously small and not worth worrying about.
A session is by default already backed by a cookie with the name phpsessionid (so that the server is able to identify the client and associate it with one of the sessions in server's memory), so your concern actually makes no sense.
It's only easier to make use of $_SESSION instead of reinventing it with a "custom cookie".
I would believe it would be about the same except the session would be coming from disk. Also the session is coming from the cookies anyways.
From a security standpoint, do you really want to be storing information on the client-side? Typically, I would not store things with the client.
While roughly equivalent from the perspective of manipulation in code, cookies and session variables are very different things.
Cookies are stored in the browser, and transmitted to the web server with each request. If you store large cookies or lots of small ones in the user's browser, you increase the size of each request/response, which makes each hit more expensive (bandwidth) and slower (time). Also, anything stored in a cookie is visible to the client, so avoid storing anything sensitive there.
Session variables, on the other hand, have their own sets of issues. Since they're stored within the server context, they don't propagate between clustered servers. If the server/service resets or the user's session times out, whatever was stored in the session[] collection is lost. Storing large data in a session variable incurs a performance penalty on the server, which can get really bad if you have a lot of traffic. Session variables require a cookie, which the server uses to identify a user's session. It is feasible for a user to alter their cookie to gain access to data stored in other sessions, though this would be pretty freakin' difficult to do with any kind of value since session IDs are randomized, nonsensical pseudo IDs.
Ultimately, all of this crap should be stored in a database anyway. Sessions are a lazy convenience that should be avoided when developing any robust application. Cookies should be used minimally - typically, I store a guid in a cookie which helps me identify a user (similiar to a sessionID cookie, but application-specific), but everything else goes in the database. This gives you server-agnostic data availability, secure storage, data lifetime set by your app instead of the server config, good query and report ability, etc.
Databases are easy when done right. There are many, many reasons that any state information you collect should be stored in a database, and no good reason not to.
In some browser it is not possible to store cookie ,to avoid this problem you can pass a SID (session id) or some hidden,filled,textbox values , instead of cookies, by using GET and POST methods.