Scope of SESSION data across different folders

Hi there,

I have a question regarding PHP session security…

My set-up is based on a number of separate instances of (the same) PHP/MySQL script being run in different subfolders of the same website.

For example, I might have 2 separate instances of the script located in the following 2 subfolders:

www.example.com/folder1/
www.example.com/folder2/

Essentially these are 2 entirely separate sites (with individual databases) that are running the same script.

My problem is that if a user originally logs in at “folder1” and then browses to “folder2”, their session will carry and they will have full access to the script in the new folder.

I have tried setting the “session.cookie_path” value within each subfolder (using a .htaccess file), so that the sessions would only be valid within the particular subfolder that they were first created. However I found that this was insecure.

As a test, I logged into the script at “folder1”. I then edited the cookie that had been set on my machine - I simply changed the cookie path back to root “/”. I then browsed to the script at “folder2” and all of my session data from “folder1” was readily available.

I would have thought that when PHP created the session in “folder1” it would have limited its scope to only that folder, but this does not appear to be the case. So, if a malicious user were to alter the path on their session cookie they would be able to carry their session data to any other folder on the domain. Has anyone else struggled with this problem?

Many Thanks,

Matt

I then edited the cookie that had been set on my machine - I simply changed the cookie path back to root “/”

Where did you do this, in the session cookie or in the .htaccess file?

from what I know, a session is available across an entire domain anywhere it is called upon, there is no discrimination between folders. between subdomains however is a different matter.
Maybe you can construct your session in such a way that it will grant access to one script, but not the other?

You can always set the path for your session cookies from the server side and thus determine which section of server a session applies to. But I am not sure if this is possible by directly changing the cookies in the client side . So wanted to know, where did he change the path?

Thanks for the replies :slight_smile:

In response to Kailash, I manually edited the session cookie in my browser, so that the path was changed from “/folder1/” to “/”. This had the effect of opening up the session variables to any other page on the same domain, including those pages located within “/folder2/”.

I was very surprised that this happened, because I would have thought that the path would have been stored with the session data on the server. I was hoping that the session variables would have then been limited to the folder where they were created.

I was very surprised that this happened, because I would have thought that the path would have been stored with the session data on the server. I was hoping that the session variables would have then been limited to the folder where they were created.

I am surprised that this worked. I will post back after I do a bit research on this one.

Each user is running the same script, but with access to a different database, yes? So having the same script in two different folders is rather inefficient and relying on the cookie path as a method of restricting access to a single folder is evidently not sufficient.

Surely it would be better to have each user in the domain accessing the same script and requiring a login. Once the user’s credentials have been established, individual DB details can be retrieved for that user.

This may seem a bit harsh… but if your intention is that your application should restrict users to specific data, then your design seems rather wrong-headed.

In principle, I agree with auricle, however at the same time I know where you’re coming from (been there, done that). In this case, your solution would be in two steps:

  1. Change session.cookie_path to the relevant directory path (you’ve already done this).
  2. Add a variable to your session (e.g. $_SESSION[‘path’]) and set that equal to the path as well. Then verify that value before granting access.

This will have a two-fold effect:
Setting the cookie path will allow casual users (i.e. those who are not manually editing their cookies) to log in to both areas simultaneously and use both, should they wish. This is a Good Thing.
Setting the session variable will give you a server-side verification of the session, allowing you to catch and terminate the sessions of wannabe-crackers. This is also a Good Thing.

Now that I’ve shown you the solution to your current dilemma, I’m going to again reiterate that I wholly agree with auricle and you need to sit down and think long and hard about why you’re running two copies of an identical script on the same domain, about why you’re running two separate “sites” on the same domain. This is, quite frankly, a bad design choice; I mean absolutely no offense when I say this, I’m just calling it how I see it.

Actually, I’m not sure we can assume that it’s two separate sites. I suspect that mattya may actually be using the same database but have each user’s data in a separate table, even if the nature of those sets is identical. There may be compelling reasons to do this.

I faced this situation recently. I’ve written an asset register as a teaching. I don’t wish to compare the work of different students; I just wish to look at what each student has done. However, because of the short timeframe, I chose to the CakePHP framework. Cake’s Model doesn’t facilitate run-time manipulation of the associated database table’s name (which would be necessary to select the right table when a user logs in). So I was forced to ditch that idea and save a “user_id” with each record entered by a specific user. Instead of querying with

SELECT * FROM custom_named_table

I have to use

SELECT * FROM assets WHERE user_id = '1'

to filter out a specific user’s data. That’s not a big deal, and in the overall scheme of things, is probably a better design.

But DB design is a different topic. The fact that the same script is in each user’s folder suggests that they’re actually running the same app, albeit with different data (and that’s the intention in fact). So I wouldn’t say they’re two different sites, any more than my own myspace login takes me to a different “site” than yours takes you to.

sessions scope is based on the cookie.

by default a cookie is valid through the entire domain, ie domain.com and and subdirectories

if you want to limit that to a specific folder then you can specify it in the session cookie params.

look on the reference page php.net under session functions, and you’ll find the one im talking about, it basically adds a parameter to the cookie so that it only is valid in the specified directory.

If you’ll read the thread, you’ll see that the point is not how to limit the scope of a session, but rather how to do so without a malicious user being able to adjust the scope himself. Cookies are editable in their entirety, including their scope. This thread has been about countering this fact.

Thanks once again for your replies…all very interesting and useful comments. I should probably explain a little more about my set-up…

I mentioned earlier that I am running the same script within 2 separate folders, accessing 2 separate databases, acting as 2 separate sites.

What I actually have is a single (common) codebase located above the web root. I have then created 2 skeletal directories (“folder1” and “folder2”) and into each of these folders I have added a config file and an index file. The config file sets up the site-specifics (like the database connection) and the index file accesses the common codebase. The index file acts as a Front Controller for the site.

This arrangement allows me to utilise the same codebase for each “site” with a very rapid set-up time, and easy management of updates. The script itself is an application that will (eventually) be used by multiple clients (each located in their own folder) which is the reason I want to keep the data separate by using separate databases for each site.

However, if I have a user who has just logged into “folder1” and they then browse to “folder2”, their session will still be valid and the chances are that it may relate to a user in the other database. I am currently setting the session.cookie_path to limit the session cookie’s scope to a particular folder, but as I have found out - this is an insecure method of limiting a users access, because the cookie path can be tampered with.

I guess the reason for posting this thread was that I was surprised that PHP does not have a feature to limit the scope of the session to a particular path on a domain, other than through setting the cookie path, which can so easily be tampered with.

I would have thought that a session path value could have been stored on the server, at the point that the session was created. PHP would only then recognise the session when pages within that path were accessed. I am sure there are reasons why this was not implemented, but it seems like a fairly straight forward feature.

I think for the time being, my best bet is to do what Kromey suggested and set a $_SESSION[‘path’] variable that I can then check to ensure a user only has access to a specific folder. I also take on board Auricle’s comments about bringing the user data together in a single database so that logins can be managed centrally. This would involve a fundamental redesign of my script, but it may well be necessary!

Thanks again,

Matt

Well, you haven’t indicated that they’re accessing the same data although the common codebase outside the webroot suggests that they might be. But each index.php might invoke a different chain of events.

If the index.php files are very similar, might it be possible to turn them into one and use an authentication and authorisation scheme to determine which data a user should be looking at?

ok but if everyone already knows that then why does this thread exist. if you guys know session scope is based on the cookie domain and path, then you ll know its the session doesnt keep info on that, and therefore youll know to just set the path in the session. as a session variable, and check the session stored path against the path in the server variable.

Hi voodoomagic, the reason I started this thread was as follows…

Whilst I was searching for a way to securely limit a session’s scope to a particular path/folder I found various posts on the Internet that suggested that PHP already came bundled with a solution in the form of the “session.cookie_path” setting.

Now, given that sessions are most often used to secure areas of a website, I was surprised that this feature of PHP could so easily be overridden by a malicious user who simply adjusts the path of his/her cookie.

I guess what I am getting at here is why the “session.cookie_path” value exists at all? It should certainly not be relied upon to secure a particular area of a website. As you have pointed out, the path would need to be stored on the server (and not in a cookie) to ensure this.

It also seems a shame that there is not a further PHP setting that would allow you to securely force the scope of a session to a particular path/folder.