tags:

views:

314

answers:

6

Hi, i'm working with sessions in PHP, and i have different applications on single domain. Problem is, that cookies are domain specific, and so session ids are sent to any page on single domain. (i don't know if there is a way to make cookies work in different way). So Session variables are visible in every page on this domain. I'm trying to implement custom session manager to overcome this behavior, but i'm not sure if i'm thinking about it right.

I want to completely avoid PHP session system, and make a global object, which would store session data and on the end of script save it to database.

  1. On first access i would generate unique session_id and create a cookie
  2. On the end of script save session data with session_id, timestamps for start of session and last access, and data from $_SERVER, such as REMOTE_ADDR, REMOTE_PORT, HTTP_USER_AGENT.
  3. On every access chceck database for session_id sent in cookie from client, check IP, Port and user agent (for security) and read data into session variable (if not expired).
  4. If session_id expired, delete from database.

That session variable would be implemented as singleton (i know i would get tight coupling with this class, but i don't know about better solution).

I'm trying to get following benefits:

  • Session variables invisible in another scripts on the same server and same domain
  • Custom management of session expiration
  • Way to see open sessions (something like list of online users)

i'm not sure if i'm overlooking any disadvantages of this solution. Is there any better way?

Thank you!!

UPDATE: i did not explain it in enough detail and caused a lot of confusion here, so i want to make clearer what i'm dealing with:

I'm building SOA server application, which would be deployed in many different enviroments. It won't have it's own webserver, so in those enviroments there could be another PHP applications. Employees of these companies will have user accounts in this application, so they will obtain a cookie with session Id into this application.

As we know, webserver running PHP when loading session data doesn't make difference (at least by default) what script from which directory created session. All it needs is a session ID. This session ID is sent with each request from client to server. From your answers i got a way, how could PHP restrict cookies for certain directory, but malicious user is able to edit cookie, because it's stored in his computer. Malicious user in my case can have access to write and execute php script in the same environment, although not having access to my application and it's database. If he create a script, he could use Session id from cookie of my application, thus he has access to read and edit session data on my application and gain access to parts of my application, that he shouldn't be allowed to.

I see there will be another security threats in deploying application in such environment, what i'm going for is the best isolation i could do, and default session handling seems too dangerous and not designed for uses like this.

So my question is, if you see something, which is less secure, less flexible in my design, than it would be with default session management..

Thank you for your answers,..

+1  A: 

Have a look at the method session_set_save_handler in PHP.

http://php.net/manual/en/function.session-set-save-handler.php

Well, to be factually correct, several companies use the approach of having custom session handlers for multi-domain, distributed in-memory/database backed session handling

MasterGaurav
Yes i did, and i don't think this solves my primary problem with session variables visibility across domain.
praksant
A: 

I want to completely avoid PHP session system, and make a global object, which would store session data and on the end of script save it to database.

If you are thinking of serializing your objects, i wont recommend as its not a good practice to hold secure details.

http://www.php.net/manual/en/function.session-set-save-handler.php#81761

Have a look at the above example, he has given a good solution.

Maintaining your state across the domains.

  1. Generate a unique Identifier first.
  2. You can create a cookie that is read on every page access. On every page access the cookie is sent from browser to server.
  3. Also you can pass your unique identifier as a part of every URL you generate, if you want another approach instead of cookie.

Update:

  1. First you need to restrict users to your application based on IP address, if you want to make it more secure which can be achived through crossdomain.xml restricting users.

  2. You need to look into encryption of your session so that even if the user breaks it up he could not use it. Data should be encrypted with private keys and decrypted using public one. The Handshake is based on public keys.

Vinothbabu
I don't understand how do you mean "not hold secure details". I wouldn't store user password, as it wouldn't serve any purpose, but every other sensitive data, on top of which is an application built, already are in the database, so i don't think that would be any less secure. What i want to store are only session data - which user is logged in, and some session settings. Maybe i should have mentioned it would be a SOA server.
praksant
If you are storing your session information and reconnecting on every access it can overhead your database and also your data must cleaned up periodically.
Vinothbabu
Connection should be opened across requests, and only queries sent on every access. PHP sessions work by default with files, but alternatively it could be switched to database. in that case it's the very same thing, as built-in db session handling, and in case of files i think it's overhead for webserver. As far as i know, databases are better optimized for this kind of data access. Also, both ways needs to be cleaned up periodically. Is there any way where this could be avoided?
praksant
Database can be optimized well for this. To avoid this you need to go out for cookie as i said earlier where your cookie is sent from browser to server. When your user jumps from domain to domain pick up the cookie data, pass it to the new domain and finally re-post with the cookie data.
Vinothbabu
I don't think we understand each other here. I have 1 domain, and more apps on it. One app is which i build, other apps should be isolated as much as possible. I explained it more in comment to Foo's answer.
praksant
I am totally confused after reading your comment to foo... can you tell me on what exactly you need. sorry... i got confused after reading that comment
Vinothbabu
I updated my question and added more explanation. Thanks
praksant
To your update:1. i don't think crossdomain.xml is the way to go here.. as far as i know, it deals with very different kind of situations2. This seems to me as an overkill. Why should i want to deal with encryption here.. HTTP communication will of course go through SSL, but encrypting session data, i don't think it would be easier or better in any way than what i proposed.
praksant
When you are going for securing your data, why not go for encryption and using public and private keys. It makes sure you are in safer side.
Vinothbabu
Well, encryption is great tool, but for a different kind of job. It's main purpose is for sending data through unsecure medium. It is made to be unreadable for third parties, which could see that data. i'm aware you are proposing it for just the same reason, but session data shouldn't be visible to third parties at all, so i'm trying to hide it instead of obfuscating it. Problem is also in your solution it's still possible to change data in session, although it's very hard to make those data valid, but i don't want to deal with that if i don't have to.
praksant
+2  A: 

You need to use:

session_set_cookie_params()

http://www.php.net/manual/en/function.session-set-cookie-params.php

In particular you need to set the "path" in each of your webapps.

Foo
yeah, i overlooked this one :) thank you,.. but when i think about it now, from security point of view, if you send that cookie (modified to work in other dirs) to another application on that server, that application will access that session data.
praksant
Each app will give out different session_id's. So they cannot access each others data.You may still have some old session data using the default "/" path however, so you need to clear cookies on your browser once the fix is in place to all apps.
Foo
Make sure you call it *before* session_start()
Foo
praksant
A: 

i'm not sure if i'm overlooking any disadvantages of this solution. Is there any better way?

its very complicated - and its not going to work, e.g. remote_port will change between requests, remote_addr may change.

There's at least 2 very obvious solutions without reinventing the way session handling works:

1) use a different cookie name for the session in each app - see session_name()

2) have each application in a different sub directory (e.g. http://example.com/app1/, http://example.com/app2/, ...) and set the path on the cookie - see session_set_cookie_params or use different ini setting for session.cookie_path

symcbean
Well, checking IP address and port it's not an essential feature, so it's not going to be a point of failure of my design. I can use it to analyze potential attacks, i can restrict selected users to use only certain range of IP addresses, i can use this information however i want, and i may not use it at all.And your solutions would work for those cookies, but i don't want session variables be visible in other application even if you hijack cookie from app1 and send it to app2. Maybe it wouldn't be hard to overcome this, but it wouldn't get me another advantages like better expiration mngmt.
praksant
Method 1 would indeed expose session ids across application. Method 2 does not. How you expire the session data is independent of how you reconcile the user to the session - what are you proposing for session expiration which is in any way better than the default method ? (I see no difference except for the increased risk of maintaining your own code for this).
symcbean
I did not say it would expose session id. I tried to explain a scenario of an attack in update to my question. Session expiration - i already have a requirement to make certain users' sessions expire after very short time. It has to be flexible, so connection from corporation IP range wouldn't need to expire as fast as connections from outside. It may be made not to expire from certain IPs for certain users at all. Let's not question security aspect of doing that, but in general, it could be very useful to have such flexibility
praksant
+1  A: 

If you don't want to have problems with shared sessions, you can use the session_save_path function to set a path where your application will save its session files. As it won't be the one used by other apps on the server, you wont run into session sharing problems.

Only one thing : make sure the path you save your session files in is not accessible from the web. Something like :

/YourAppFolder
     /www (web accessible)
     / libs
     /config
     / session (where you put your session files)
Arkh
+1  A: 

Here's what you can look into:

  • Set the session ID's path and domain. If the domain is .mastergaurav.com, the cookies will be sent back to mastergaurav.com, www.mastergaurav.com, blogs.mastergaurav.com etc
  • May be, instead of using session ID as cookie - if you have to really traverse multiple TLD domains - , make it a part of the URL for completely custom implementation:
    abcd.php?<?php echo session_name(); ?>=<?php echo session_id(); ?>&domain=<your-domain>
MasterGaurav
I don't think you got my problem. I don't deal with multiple domains/subdomains, and even if i was, i think it wouldn't solve any of my subproblems
praksant