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
Related
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 coding a private message system in PHP for secure encrypted communications.
Every time a user registers an account, I'll create a new RSA private key using phpseclib and will encrypt it in AES using the user's password, which will be securely stored hashed and salted in the database.
Every time a user logs in with his password, he should also unlock his private key and maintain it on the fly.
This script is obviously intended to run only under SSL connections.
The problem is that I need to maintain a non-encrypted version of the private key in the user's session to make sure he is able to read every message and write new messages without inserting the password on every page refresh.
Storing in the PHP Session is not a secure solution since the PHP Sessions are still stored on the server and can be compromised.
Storing it in a Cookie is not a good solution since a Cookie can be easily stolen (but in this way I put the destiny of the user in his own hands).
Is it possibile with ajax to maintain the key in a PHP variable (not Session) and never refresh the page but getting and writing messages using ajax? or is there a better solution?
Thanks in advance.
Assuming you have full control and can limit access/visibility to your database, you can switch over storing your session data from file storage to using database as session store. This assumes of course your db is secure enough for your needs. You can check out a detailed overview on how to setup php for storing session to your database here: http://www.stanford.edu/dept/its/communications/webservices/wiki/index.php/How_to_use_MySQL-based_sessions
Assuming you don't need to preserve session data across a database restart, you could also make the session store table's storage engine to be MEMORY instead of Innodb or MyISAM. This will make it pretty snappy and avoid the concern you might have of session data being inside the db files on disk in an unencrypted state.
If you store the private key anywhere on the server, then it's only as safe as your trust in anyone who has root access to that server. For a secure messaging system, not all your users may want to trust the people who can access root. (Do they?) That suggests you'd want to store the private key on the user's machine. As you suggested, doing that is a whole different set of security questions.
I'm assuming your users are using web browsers to access your system, since you mentioned cookies. Most web browsers also support the idea of local storage (non-cookie), which might be an option to investigate; I'm not expert at all in that area so won't comment further.
Security is hard, and complex. Be wary of any simple answers, and be aware that no security is perfect. Good luck.
I have a question regarding usage of cookies for standard login purposes. Say my php script saves a cookie into a users computer each time he logs in. The cookie value is say "Mike" after his username at the website. Can that user somehow manipulate that cookie in his browser to change the value to say "Admin" so suddenly he has access to administration of the website?
If this could happen how to solve such security risk?
--
Additionally... What if someone was to copy cookies from my browser, either he would stare at my computer screen and copy cookies and values into his computer or such intruder could steal cookies from my browser via JavaScript.
How is that taken care of?
Yes, that is a security problem, which extends to any information provided by the client.
Cookies are stored on the user's machine. They can be modified in any way. In fact, the cookies can just be created on the fly and sent via several utilities for making HTTP requests. It isn't even a browser problem.
Never trust any data that comes from the client.
Yes, a user can manipulate cookies if they're stored on their computer.
Use a session.
A 'session' is the server-side storage of connection-relative information that is linked to the user through a variable which is passed back and forth, most often a cookie, however logically, anywhere will do if both your client and server can handle it.
This 'session' is often represented by an integer which the client and server both know.
The problem is, if another client has a session open on the server, we (as a client) could 'hi-jack' this session by replacing our given id with a random id until one is found. The server would now believe we are in fact the other use and could give us access to their private informatin.
For this reason, we have 'keys'. A key is a unique, often alphanumeric, code which is changed on each request-response pair with the server, ensuring that only those who have the latest key are able to gain access.
YES
They can manipulate, edit, modify, create and delete cookies.
You should only store a hash key that you use on the server to look up in a database anything that should be secure.
Yes, users can manipulate cookies. The best way to handle it is to not store user credentials in such a manner that they can gain admin access by changing their user name.
The specifics on how to do this are pretty deep, but a good start would be to just store the users's session identifier instead. That has its own issues, but won't let people break things quite so easily.
Cookies are clientside which means that they can be read, write and delete by the client. A cookie manager plugin makes it easier to change the cookie value.
http://www.ehow.com/how_7149468_edit-cookies-computer.html
Yes a user can easily manipulate the cookies by just going to cooking option which all popular browser provide
Please read this THOUROUGHLY before voting...
So I have seen a lot of session management classes that create a fingerprint via concatenation of user agent and a couple of ip blocks or whatever. They seem to also add a salt and then hash this fingerprint before storing it in a session variable.
This fingerprint generation typically happens every request in order to verify that the current user of the session is in deed the original session user. This is why I am wondering, is the salt and hash really necessary on something like this?
If a hacker can get onto your filesystem to see your session file contents, aren't you already hosed at that point?
Any info greatly appreciated.
Most of it makes sense, but the hashing and salting makes no sense.
If you tie the session to an IP address, then it becomes a lot harder to hijack into a session. This is something I recommend doing, but you don't need to be utterly strict about it. You can just tie to the first three parts of the IPv4 or so. The choice is yours. The more strict IP check the more secure it is, but the less convenient it is for users.
And as for tying the session based on the user agent, that may also help. It must be realized that if you work on an unencrypted channel (HTTP for example), then the user agent check is less useful as it can be reproduced by the intruder as well.
When it comes to salting and hashing, that is useless. They add no strength to your identity checks. The only thing they do is complicate your design. For this matter, I believe they lower your level of security.
As always, a few rules to keep in mind:
Use strong session identifiers. This means use good random sources and make sure there are enough bits.
Tie the session to an IP, at least to some extent.
Tie the session to a user agent, if possible.
Use SSL/TLS. Without it, theoretically all session systems are insecure.
Secure your session storage. Whether it's filesystem based or database based.
I can think of two cases where it would be useful:
When the session data is stored client-side. (Like in a cookie.) So, I'd be prevented from taking my cookie to another computer, and I'd be prevented from making up my own cookie contents. (Ok, so this is not a very likely scenario...)
When the session data is stored in some shared server-side resource (i.e., /tmp) and is vulnerable to snooping. In this case, if the snooper is able to see the contents of the session, they'll still be unable to fake a connection to that session because they don't know what data went into the fingerprint.
In complement to the response of #Kai Sellgren (+1) which contains some good hints on how to secure your session storage I would add some ideas than can explain the hash & salt on some specific applications.
I'm not talking of application that are using the cookie as a session storage, we still see this for example on Prestashop eCommerce solution, with encryption of the cookie content (why the hell did they decide to store the session on the cookie?). I understand we talk about server side session storage.
The key point is layered Security and in-depth defense:
Compromissions are never boolean things, your are not 'completly compromised' or 'completly secure'. One of the the real history I like about that is the mySpace worm explanation, it shows a real attack and how defensive steps must be break. There's always a new wall. Just one example, I share the same IP as my boss when i'm in the office, and maybe the same browser, this could break a security based only on IP+user-agent.
So in the hash & salt of session stamping we are clearly acting after a few walls have fallen. And kai shows us some of these walls. When he talks about securing the session storage I would add 2 things:
it's a really good idea to alter the session.save_path and the open_basedir of each PHP application (and get a separate Virtualhost for each). Rarely done.
if your application is installed on a path (like /myapp), add a prefix_path on the session cookie (and fix it for any other app on the same server)
Now Let's imagine a realistic compromission. You've several ways to compromise the session on the server side:
The application is running on a website with some other applications running in other paths (or in other domains in the same server). And at least on of theses applications is quite unsecure. At worst server side code could be injected in this app, but some of the security walls (like open_basedir or other chrooting techniques) may prevent this injected code from affecting your separate application (or data).
Some of the javascript libraries comes with some test subdirectories containing highly insecure scripts, with not only nice session disclosure but maybe some session fixation or prediction available.
The application is shared, and talking about wordpress-like softs you can imagine some platforms sharing a lot of different installations, with different modules and maybe some custom code. On such platforms you'll find settings to allow altering the salt for each consumer, there's a reason for that. One of the website could impact the security of others and clean separation can be harder to do if the applications wants to manage the websites all-in-one.
Your targeted application may get hit by the environment, if the session storage can be shared with some scripts from other application, or from a script in your own application that you did'nt even notice (like these f*** examples in javascript libs, why didn't you suspend php execution on static file directories!)
From this first step of compromission the attacker could potentialy (and in severity increasing):
read the session stamps and maybe find which information he should fake to get the same stamp
build a new session containing a session stamp valid for his configuration, and then use this new session identifier on your application. Your application will find the session file, and accept him.
alter one of your valid session to modify the stamp in the same way
A simple hash of the stamp would make his life harder, but it would just be a wall to break, the salt make this wall really harder to break.
One important point is, from your question, if a guy can alter something in the session storage am I already in a bad mood?. Well, maybe not completly. If it is the only thing the chroot/separation/securization of applications allows him to do this salt will be a nightmare for him.
And the second important point is: should I do this level of in-depth security on every web application?. Answer is no. Overengineering is a bad thing and can reduce the security of your application by the simple fact it became harder to understand and maitin. You do not need to complexify your application if:
you've got a pretty good level of session storage separation
you're alone on your server, only one application, and not any sort of multisite handling
your application security level is so weak that a simple code injection is available on the application, so a session fixation is not needed for an attacker :-)
I can imagine that the point of hashing that fingerprint information is storage space as the resulting hash has a fixed length.
But to also use a salt doesn’t make much sense to me. Because, as you’ve already said, since that data is stored in the session data storage location, you would already have a bigger problem than session fixation/hijacking if someone would be able to obtain that data.
You can find a plausible solution here:
http://shiflett.org/articles/the-truth-about-sessions
Fingerprinting combats session hijacking.
The attacker not only needs your session_id, he also needs any sensitive HTTP headers.
It adds another barrier for the attacker, albeit one that can be easily overcome.
The hash is there to make the data uniform. The salt is there to obscure the hashing process - so an attacker can not generate a valid fingerprint for his own combination of HTTP headers.
If a hacker is in your filesystem you have bigger problems :D
A lot of people who don't understand very much about security combine bits of advice floating around the internet in the hope that what they end up with will be "good enough". Tying the session ID to the U-A breaks browser upgrades (which Chrome does fairly often) and tying to the IP address breaks mobility (anyone with a laptop that uses Wi-Fi), and many ISPs don't have contiguous allocations. Anyone who can sniff cookies can also sniff the U-A, and will probably have access to the same IP address because they got the cookie off insecure Wi-Fi behind a NAT.
What you probably do want to do is change the session ID on a login attempt, which is a reliable way to prevent "session fixation" attacks (where the attacker makes the victim load http://example.com/?SESSIONID=foo e.g. through an <img>, waits for you to log in, and now knows the victim's session ID). There is little reason to preserve a session across a login, and you can copy the few things that need to be preserved (e.g. a shopping cart) across.
If a hacker can get onto you
filesystem to see your session file
contents, aren't you already hosed at
that point?
If you are using PHP as CGI (like in the case with nginx), then I think no. If you set permissions right then your session files must have read/write permission for PHP user while your PHP files should have only read permissions. So, if you pass the salt from the web server to PHP, then PHP user can't get access to it (he can't create any new/change existing PHP files that can be run by your web server and he can't access web server as it is run on another user), so he can't really hack(change) cookies (only delete them) because he can't get salt. Of course you will have to pass database settings from web server as well.
I never really tried it, so please correct me if I am wrong.
is the salt and hash really necessary on something like this [http client fingerprint]?
The hash might be useful to reduce the number of bytes consumed by the fingerprint inside the session data. So as long as the hashed fingerprint is of a smaller size than the fingerprint itself this can make sense in terms of space reduction. Price is the consumption of system resources to generate the hash.
Does it really make sense? You would need to benchmark this to say so.
How can a salt be helpful then? I must admit, I see no reason for a salt. It would only make sense to make it harder to guess the fingerprint from a hash. But as I do not see any security benefit in hashing the fingerprint (it's kept on the server-side only and is already considerably secure), salting is not adding anything.
In case the session store itself is not considered secure (if that's for the argument), the whole session should be encrypted, not only the fingerprint.
So particularly for the fingerprint, I do not see much use in hashing and salting it.
I know about all the issues with session fixation and hijacking. My question is really basic: I want to create an authentication system with PHP. For that, after the login, I would just store the user id in the session.
But: I've seen some people do weird things like generating a GUID for each user and session and storing that instead of just the user id in the session. Why?
The content of a session cannot be obtained by a client - or can it?
You're correct. The client just sees a randomly generated session id token. There are ways this token can be misused (hijacked, etc.), but having a GUID on top adds nothing. In contrast, options like session.cookie_httponly (JavaScript can't see session cookie) session.cookie_secure (Cookie can only be transmitted over HTTPS) protect against certain attack scenarios.
The short answer is that $_SESSION is safe and you do not need to worry about its contents being leaked to a user or attacker.
The content of the session is not normally be accessible to the user. You should be able to store the user's primary key and you'll be fine. There are cases where the session can be leaked, on a normal linux system the session folder is in /tmp, however this could be changed in your php.ini to the web root (/var/www/tmp) and then could be accessible. The only other way is if the user is able to get access to the $_SESSION super global by hijacking a call to eval() or by the variable being printed normally.
If you are running on a shared host and using an old version of PHP and/or your server is misconfigured it might be possible for another user on this system to read or even modify a session file stored in /tmp/. I don't know of a single application that takes this attack into consideration. If this is a problem you can store the information in a session table in the database.
Sometimes, for added security, developers may assign a long string to the user's session in order to make hijacking even more difficult. By setting a cookie with this new string at the time of session creation, the app can check for the correct string on subsequent requests to better ensure it is the person who actually logged in.
It's just adding one more thing a wannabe hijacker would have to guess. However, it can be a false sense of security as it does little to protect the session if sniffing is involved because the new cookie is sent right along with the php session cookie. Also, session id's are very hard to guess as it is (as I'm sure you know, just don't place it in the url but, rather, in the cookie).
Session info is stored on the harddrive so it's not obtainable by clients without application intervention.
I've never seen GUIDs being used for sessions, but there are a couple of additional methods I have seen that do add a little more security.
Storing the user's IP - if you need to force a session change based on locations (sometimes geoIP stuff will do this)
Storing the user's HTTP_USER_AGENT header string. Can provide a bit of security against hijacking if the hijacker happens to be using a different browser.
There's a great article on session hijacking countermeasures on Wikipedia, actually.
That being said, I would imagine that anyone storing a GUID as part of a session to use in session security might be failing to see a better solution (such as session regeneration). I can see other uses for a GUID to be stored (maybe it's part of a random generator for a game), but not for use with session security.