NotionCommotion Posted November 11, 2014 Share Posted November 11, 2014 If I have three files such as the following, and put session_start() in each, the session cookie will be domain: "mydomain.com" and path "/". As such, the session will be shared between all three files. http://mydomain.com/index.php http://mydomain.com/folder1/index.php http://mydomain.com/folder1/folder2/index.php If I want the cookie to be unique to each file, then it seems I have several options. I could use session_name() to give the cookie a unique name for each file. I could use session_set_cookie_params() to set a unique path for each (/, /folder1, /folder1/folder2), however, the index files in the children directories will also be sent the root directories session cookie, right? Will this cause problems? Should both approaches be implemented? Or is there another approach? Thanks Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted November 11, 2014 Share Posted November 11, 2014 Neither of this is a good idea. When things get weird and hacky, that usually means the approach itself is flawed. If you want to separate the scripts so strictly that they don't even share the session, then they should in fact be on separate domains or at least directories (with no common prefix). This is a clear and robust solution and lets you avoid any confusing hacks. Also note that PHP itself doesn't enforce the separation of sessions. All the parameters (name, domain, path etc.) only refer to the session cookies. The client is free to change them and use the session anywhere. To get actual separation, you have to store the information server-side (in the session itself, the database or whatever). Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted November 11, 2014 Author Share Posted November 11, 2014 Thanks Jacques1, I agree that when things get weird and hacky, it is usually a flawed implementation, and would appreciate some more input. I posted a somewhat related question http://forums.phpfreaks.com/topic/292405-how-to-structure-website-with-accompanied-microsites/ which is not exact, but provides some background. I have a public website where people can look at the application, and signup if they want. Currently, I have this at http://mydomain.com/index.php. Sessions are only used to support the site creation phase (you've done part, and only need to click a link on your email), and doesn't deal with user logons. If they sign up, they select a "domain name" (not really a domain name, but it differentiates their site kind of like a WordPress.com or Facebook account does) and they get two websites. Assuming they picked the name "bobs_site", their two sites will be http://mydomain.com/bobs_site/index.php and http://mydomain.com/bobs_site/administrator/index.php. The two sites are completely separate and an admin user doesn't have access to the frontend using their admin username/password. Normally the user who signed up will only visit the administrator portion, and the user's customers will visit the other portion, however, the user will likely wish to see what the other portion looks like so may create a frontend logon for himself and log on as well. You provided the following advise: If you want to separate the scripts so strictly that they don't even share the session, then they should in fact be on separate domains or at least directories (with no common prefix). This is a clear and robust solution and lets you avoid any confusing hacks. Could you elaborate on this topic, and how it might apply to my scenario? Thank you Quote Link to comment Share on other sites More sharing options...
kicken Posted November 11, 2014 Share Posted November 11, 2014 Each user should have their own sub domain, for example bobs-site.mydomain.com. That way there will be no possible confusion as to which cookies apply to which site by the browser. As for using separate sessions for the administration area and the main site, don't. Use a single session and just manage the credentials appropriately in the code. For example you could store all the administration related session data in $_SESSION['administration']. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted November 11, 2014 Share Posted November 11, 2014 You must have a separate domain and session for the admin pages. If you don't, then any vulnerability on the main site is likely to compromise the admin account as well, because there's no barrier between the two. For example, a malicious JavaScript snippet on john.yoursite.com can read and change arbitrary data on john.yoursite.com/admin. Actually, if you were to use paths instead of subdomains for the user sites, then anybody could access any admin area simply by getting the other user to visit their site. For example, yoursite.com/alice could access yoursite.com/bob/administrator via JavaScript, because they're both within the same origin. So you do need a separate admin subdomain to protect the admin account in case the main site gets compromised. Letting users “create” their own subdomains as suggested by kicken is also very problematic, because then there's no clear distinction between your content and the content of your users. For example, what if somebody registers a domain like payment.yoursite.com or admin.yoursite.com? This may even be abused for phishing-like attacks. If you do want to take this risk, do everything to avoid confusion between user-provided content and “official” content: Use special prefixes like “user_” for the subdomains or even sub-subdomains: joe.users.yoursite.com Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted November 11, 2014 Author Share Posted November 11, 2014 Each user should have their own sub domain, for example bobs-site.mydomain.com. That way there will be no possible confusion as to which cookies apply to which site by the browser. As for using separate sessions for the administration area and the main site, don't. Use a single session and just manage the credentials appropriately in the code. For example you could store all the administration related session data in $_SESSION['administration']. Understand the recommendation about managing session credentials via code. Easy enough. Does this also provide reasonable protection between front and admin sites? In regards to each user site having its own sub domain, how is this implemented? My wildest dreams suggest 100,000 subdomains . If I don't have 1,000 subdomains, I failed. Do you know if that is how wordpress.com does it? For instance, I have a wonderful site https://notioncommotion.wordpress.com/. Think it is a unique domain? Think they created some folder just for me? Or is wordpress.com's implementation inherently insecure, and I should not attempt to mimic it? Or maybe I shouldn't even be creating separate folders for each site. Instead, I have something like http://mydomain.com/index.php?site=folder1 and http://mydomain.com/index.php?site=folder1&type=admin, and use the webserver to rewrite it. Can it be implemented securely? If so, please provide general description of approach. Thank you Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted November 12, 2014 Author Share Posted November 12, 2014 You must have a separate domain and session for the admin pages. If you don't, then any vulnerability on the main site is likely to compromise the admin account as well, because there's no barrier between the two. For example, a malicious JavaScript snippet on john.yoursite.com can read and change arbitrary data on john.yoursite.com/admin. Actually, if you were to use paths instead of subdomains for the user sites, then anybody could access any admin area simply by getting the other user to visit their site. For example, yoursite.com/alice could access yoursite.com/bob/administrator via JavaScript, because they're both within the same origin. So you do need a separate admin subdomain to protect the admin account in case the main site gets compromised. Letting users “create” their own subdomains as suggested by kicken is also very problematic, because then there's no clear distinction between your content and the content of your users. For example, what if somebody registers a domain like payment.yoursite.com or admin.yoursite.com? This may even be abused for phishing-like attacks. If you do want to take this risk, do everything to avoid confusion between user-provided content and “official” content: Use special prefixes like “user_” for the subdomains or even sub-subdomains: joe.users.yoursite.com I am obviously way over my head. Currently, a user logged on to john.yoursite.com can do very little. They can view information, and do a couple of heavily validated SELECT menu post updates. That's not to say this is a smart approach as things seem to change and maybe it will not be so safe in the future. The admin user does have the ability to add HTML, however, I am using http://htmlpurifier.org/ to in theory make it safe. I guess I (kind of) understand the part about a good guy visiting a bad guy's site, and getting a cookie. But what if the session array was broken down by site accessed name, and the application only allows access based on the URL? also, is my http://mydomain.com/index.php?site=folder1&type=admin idea totally fubar? Quote Link to comment Share on other sites More sharing options...
kicken Posted November 12, 2014 Share Posted November 12, 2014 The way you would handle the sub domains is by just configuring a wild-card vhost and then in your application code you inspect which request the domain was made with. list($subdomain,$domain) = explode('.', $_SERVER['HTTP_HOST'], 2); //Assumes only a single level of subdomain //use $subdomain to load the appropriate configuration I have no idea if that is how wordpress has their system setup, but I would assume it is similar at least. Having a separate copy of your application for every user is unnecessary, just have a single copy that is multi-domain aware. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted November 12, 2014 Author Share Posted November 12, 2014 Thanks kicken, I wasn't implying that a separate copy of my application will be used for each user, but that something unique would be made available for each user, and the application would configure things as appropriate. Sounds like we are on the same page. I take it that "configuring a wild-card vhost" is a Apache (or similar) configuration, and will it send all requests regardless of the subdomain to the same file, right? So then, I don't need a separate folder for each user? Sounds great! My virtual host is already created with a wildname, no? (see below). But this will not magically allow janedoe.mysite.com to work. Can you give me some points on where to? NameVirtualHost *:443 <VirtualHost *:443> bla bla bla Thank you Quote Link to comment Share on other sites More sharing options...
kicken Posted November 12, 2014 Share Posted November 12, 2014 My virtual host is already created with a wildname, no? (see below). NameVirtualHost *:443 <VirtualHost *:443> bla bla blaThank you Not exactly. The * there means "any interface" meaning if your computer had multiple network interfaces/IP addresses apache would listen and respond on all of them. To setup a virtual host to allow a wildcard subdomain you'd use ServerAlias. For example: NameVirtualHost *:443 <VirtualHost *:443> ServerName u.domain.com ServerAlias *.u.domain.com That would respond to requests for u.domain.com or anything.u.domain.com. Just setup your application the parse the domain name and configure itself accordingly. If you wanted to give users the option of using their own full domain rather than a sub-domain then you'd just add additional ServerAlias lines for each domain and ensure the app can handle it. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted November 12, 2014 Share Posted November 12, 2014 (edited) I guess I (kind of) understand the part about a good guy visiting a bad guy's site, and getting a cookie. No, I mean that any site can trigger arbitrary requests to any other site within the same domain. This is a huge problem. If a user visits a site, then this site can see any content and take any action on behalf of the user. The site essentially becomes the user and gets all their rights. For example, they're suddenly allowed to use the admin area of an entirely unrelated site. Relying on HTMLPurifier alone to remove all bad code is not a good idea. It's a great tool to increase security, but it's not the ultimate solution. You may also need to enable custom JavaScript code in the future (who wants a purely static website?). The solution is to put the user sites and admin areas behind separate domains so that they cannot access each other. For example: joe.user-sites.yoursite.com joe.site-admin.yoursite.com This still isn't perfect, because subdomains can set cookies for parent domains. For example, joe.users.yoursite.com could create a “global” cookie for .users.yoursite.com which is also valid for other user sites. But compared to the zero-security approach where everything is on one domain, this is a big step forward. But what if the session array was broken down by site accessed name, and the application only allows access based on the URL? I don't know what you mean by that. The attack scenario is that the malicious site delivers JavaScript code which is executed by the victim. The victim would then unknowingly make requests, and there's no way for you to detect that (the referrer would theoretically give away the origin of the request, but it may not be present at all). Edited November 12, 2014 by Jacques1 Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted November 12, 2014 Author Share Posted November 12, 2014 Thanks Kicken. I will check out ServerAlias! I was able to get a subdomain working earlier today, but had to go to my domain name host (1&1), and create a subdomain for my primary domain and point that name to my server. I will contact 1&1, but hopefully there is a better way. Thanks Jacque1. As you could tell, I am very new to subdomains, but very excited on the opportunities that they might provide. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted November 13, 2014 Author Share Posted November 13, 2014 Thank you all for your replies. Subdomains turned out to be just the ticket (I hope!). Step 1: I set up my DNS for mysite.com, *.mysite.com, and *.*.mysite.com to go to the same file. Step 2: Apache redirects www (or PHP just strips it off), and deals with ServerAlias. Step 3: Do the following: $domain=explode('.', $_SERVER['HTTP_HOST']); switch($domain) { case 1: //Display front site. case 2: //If $domain[1] exists in DB, display user site, else display warning page. case 3: //If $domain[1] exists in DB AND $domain[2]==admin name (as stored in DB for $domain[1]), display admin site, else display warning site. default: //display warning page } Questions Do I have the correct workflow? (see question 4 which might indicated that I need to change it) Can I rely on $_SERVER['HTTP_HOST']? It is provided by the client (bad), but verified by the webserver (good), so it should be fine, right? If I use sessions on all three and don't change the name, for the admin site, I will have (3) cookies all named PHPSESSID with the same path but different domains. Will the cookie with the same domain as the admin page always take precedent? Should I rename all three to have unique names? By the way, this was the original intent of what turned out to be an off-topic title to this thread. Currently, a user cannot add content (and thus JavaScript) to mysite.com and joes_site.mysite.com, so I have no risks, but that might change in the future. As stated in Question 3, admin site includes its own session cookie as well as session cookies for main site and user site, and user site includes its own session cookie as well as session cookies for main site. Jacques1 recommends using domains joe.user-sites.mysite.com and joe.site-admin.mysite.com (and I suppose I could main.mysite.com as well from the "corporate" site). I guess this makes sense, but I obviously don't want the user to have to enter "user-sites" in the URL. Just use Apache to rewrite and add it? Also, Jacques1 indicated that there is a risk for “global” cookie for .users.yoursite.com which is also valid for other user sites. How is this mitigated? Thank you all for your help! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.