I was wondering what kind of security measurs people use for e-commerce applications. My registration forms always use capthas - against spam. I always create unique usernames and passwords for my users. The password is, of course, hashed with "salt" before it is entered into the DB. As for the session data itself, I simply store a session id, a user name and a permission variable that helps me tell the difference between different kinds of users: clients, administrators etc. Before handling critical functions like credit card operations I also ask my users to re-enter their passwords. Of course the sites have to use some sort of SSL encryption. Is there anything I'm missing? Do people use cookies to store passwords? If so, I assume these are hashed, but do most simply store the actual hashed value along with a username and then query the DB for these exact values? This doesn't seem secure enough... Could anyone please share some of their secrets. What, in your opinion, is the safest method arround?
NEVER store any sensitive data in cookies, even if it is hashed, it's unecessary, it's a common practice to store entire sessions in databases, and have authenticated and unauthenticated sessions, you can then store the session id in a cookie and use that to verify if the user has permission to do whatever they are doing. Your safe to store usernames and whatever in cookies, makes for easy welcome $_COOKIE['name'] but any sensitive data should be kept as securely as possible, once you have authenticated a session there is no need for the password to float about anymore, having calls to an auth function on every page a user is on is a bad idea, and I assume that is why you want to keep the password kicking about .....
Do you mean you store all of the session data in let's say a DB table called sessions, store the table key as a session varriable and then query the table on each secure page using the table key from the session? That seems more secure than storing everything in session varriables, but how does it effect performance? If that isn't what you meant, could you please explain a little more? Any other tips desides that?
Yeah exactly that, everytime a new visitor comes ( or logs in and starts a session ), insert a new row identified by the session id, wack an ip address thier useragent and whatever in there ( this is helpful for detecting if someone is trying to fuck about with your authentication, for instance if the ip changes or useragent the session should end automatically, and the user logged out ), when they have authenticated themselves with a user/pass set an enum field to 1....that's pretty much it. Performance wont really be affected, you can flush out unused sessions every x amount of minutes or hours, and it's only one associative array to get all the information you need without having to retrieve the password more than once ( on autentication ). It really depends on what sort of application you have, on some scripts I don't even go to all that trouble, when a user logs in with a user/pass combination I'll store a cookie that expires in X amount of minutes with a username, I'll also use some server side check and a session at the same time, such as the UA thing an IP checks. You know it might be a better idea to just post your code and we can pick out the bits that are vulnerable and suggest an alternative that's not too difficult to implement. I'd estimate on page load vb probably retrieves about 50 or more associative arrays from mysql, that is on a full page of posts.
Well my one suggestion about using sessions is don't use PHP's built in session storing. Just to keep things simple make use of session_set_save_handler (http://php.net/manual/en/function.session-set-save-handler.php) and have it make writes to a database. That way you can still use $_SESSION and some of the other PHP abilities but not have to worry about your sessions being stored in tmp with everyone elses on a server.
Here's something I wrote about cookies a few days ago. Might be helpful for you. http://forums.digitalpoint.com/showthread.php?t=365334 The thing about this is, that the user can have a dynamic IP address, and it can change completely during the session. So I'm not 100% sure if that's a reliable way. And here's an interesting eBook about session security. If you have some time, give it a read. It's not too long. http://www.acros.si/papers/session_fixation.pdf
I see what you mean, but if you get disconnected from the internet, which you have to be to renew your ip address, you would expect to be logged off whatever sites you were on, so it's not really an issue, and it's better than leaving yourself open to session hijacking of any sort.
AOL users can have their IP address change right in the middle of browsing (without disconnecting). Even as often as every page request, according to one SitePoint blog - it's in the same post as the link to the paper nico_swd posted, Notes on PHP Session Security
Yes, I've had users complain when I used a strict policy on "remember me" features where some users were not "remembered" after a quick reboot or after a break long enough that the session expires. But I stick to it and just include a notice with the "remember me" feature. At most an option to lower security on a per account basis with a warning mentioning the possibility of the cookie being stolen. But then again, with the majority of browsers, and SIDs in URLs usually off when cookies are used, the only way someone is going to steal a cookie is by fooling them into clicking a JS link (or they could try hacking their computer!). Even that is a low possibility as it has to be on the same site and most apps protect against links with JS submitted in posts/other.
First, I would like to thank everyone for participating. Second, I would like to thank krakjoe for his input. I will definitely implement the strategy you suggested. Since I'm building an e-commerce application, I am very concerned with security and am therefore willing to handle the few unsatisfied users that have to log in again if their session ID is lost. Rep added. I studied the eBokk nico_swd provided. Thanks, rep added. But I now have a new set of concerns. More specifically, I am worried about session fixation problems that can arise if the attacker is able to send an html email to one of the other users and by doing so, lure that user into clicking his link, thereby forcing the creation of a specific session ID and coupling it with the user's ip address and useragent. The method krakjoe recommended would still be vulnerable to this sort of attack. The article nico_swd sent mentions some ways of overcoming the problem, but I'm not sure about how one might code the solution. Here are some of the problems I have: 1. the article states I must adopt "forceful prevention of logging into a chosen session" - one that is determined by the attacker. How can I code this? 2. restricting the session ID usage by: a. binding the ID to the browser's network address (ip address??) - solution already provided by krakjoe. b. binding the session ID to the user's SSL client certificate. Will be implemented once I choose the SSL provider. c. session destruction must take place on the server - goes without saying, as far as I'm concerned. d. User must be able to logout - goes without saying. e. Absolute session timeout - how can I code this? Could anyone please give me some hints as to what can be done? I imagine this topic will interest a lot of other programmers, not just me...
For example by verifying the user agent, or IP address, as Krakjoe suggested. Or any other data that is related to the current user, which doesn't change during the session. Also, for important tasks, you should always make the user re-enter his username and password. So if somehow the attacker gets into someone's account, he won't be able to damage it, or do things he's not supposed to, as he doesn't know the password. SSL stands for Secure Sockets Layer, and means basically https. Most hosts support this, and/or you can activate it in your control panel. Depends on your system. If you're using a database, you can store the timestamp of the last move in a field for the current session. Each time the user makes a new page request, this timestamp will be pulled and compared with the current one. If it's too old, log the user out, or require re-authentication. If you're using the standard sessions, where the data is stored on the server, you can set session.gc_maxlifetime via ini_set() to a specific value. (In seconds) ini_set('session.gc_maxlifetime', '18000'); PHP: The sooner the session expires, the more secure it is. Because the attacker has less time to react. This may be annoying for your users, but in the end security is what counts. Also, setting the session save path to another one than the default should make it a little more secure. http://www.php.net/session_save_path
This might be a problem for some people behind proxies (which can change the useragent over the session, or even have multiple IP).
^^ I still think it's something you can rely on. This may happens to 1 out of 2000 users. So, if we shouldn't use IPs and user agents, what else do you suggest? I can't think of anything else that remains the same during the session, and helps to identify the user...
That's kinda the whole point - there's nothing that can identify the user, hence stateless. I assume you just made up the 1 in 2000 statistic but if it may affect everyone using AOL (the most common example of a constantly changing IP), surely it's worth taking into consideration? Personally I'd consider it safe to assume the user agent would remain constant but not necessarily the IP address. Of course, the appropriate balance between security and usability entirely depends on the application.. but really, there's no solution and where it matters, you can only prevent any unauthorized use by requesting the password again. Well, not entirely prevent it, just ensure it doesn't occur as a result of flaws within the code.
This is the way I do it. I have a main user accounts table Users: user_id | username | password | authority | firstname | lastname | etc etc Then I have a session table: session_id | user_id | current_page | last_movement everytime anyone moves regardless of logged session_id will contain their php_session_id value. If the user_id = 0 then they are a guest, if > 0 then it will correlate to the users table which can be queried for their status. So on every page if absolutely no other queries happen regardless of the status their will be a query to retrieve the user data based on their session_id, as well as a update to the current page and last movement. I do not have a single variable stored in the session variables (save the session_id, but this is already generated). As well, I clear the table for every movement that hasn't been made in the last 30 minutes. If the user actually logs out in the session table the user id to their session is set back to '0', and their session_id is regenerated and updated in table accordingly. This is nice also because you can then query the session table for how many people you have online, where they are at, who are registered / guests etc.
MartiCode suggested that users behind proxies might change useragent during a session and many others suggested that users may change ips - AOL users, for example. What about using one or the other? So the session terminates only if the user somehow switches both the ip and the user agent. Would this sort of check make life easier or harder for attackers? I don't see how an attacker could maintain the user's ip. If so, he would have to maintain the user's useragent, which is the same as only checking for the useragent. I think this could make for a good balance between usability and security. If the user logs out, all that happens is that he must login again - not that big a deal. What do you think?
That post on sitepoint was made in 2004, it's information is outdated, almost all major ISP's use IPv6 based networks ( even if you don't recieve an ipv6 address ), I highly doubt that they bother changin ip addresses so often anymore, it would be FAR TOO MUCH strain on an already strianed infrastructure.
Your right, it's probably not as often anymore but unless you have anything of a more factual nature than merely your "doubts", I still see no reason to start trusting IP addresses. How often it actually changes is almost irrelevant - if a user could be midway through a session when their IP address legitimately changes, they should not be logged out. Sure, if it only changes every few months, the chances of accidently logging someone out is much much less. However from my own experience working on a fairly busy forum, we still occasionally got people asking why they were suddenly logged out for no reason (and that's just those that posted about it, most people would probably log back in and not bother mentioning it). All those concerned had an AOL IP address.. that part of the session code has since been updated not to include IP address in the session validation and there have been no more problems. Of course, I'd be very interested to hear if you do have something substantial to back up your point of view though.