I run foo.com. I have two different applications that live in foo.com: one is foo.com/bar, and the other is foo.com/example. I use sessions to track information about the user while they're logged in, but if the user goes from foo.com/bar to foo.com/example, foo.com/example sees the session the user started from foo.com/bar and uses that information. My question is, how can I have two different sessions going for each directory at the same time?
You should call session_name before calling session_start. This sets the name of the cookie used to identify the session (by default this is PHPSESSID).
Use a different name for each application. You shouldn't have to mess with the variables inside the session.
I think it's very important to highlight the potential security implications associated with the solutions provided so far.
I have been a web application penetration tester for about 5 years and have developed numerous vulnerable security applications in this time to assist with training of juniors starting out in IT security.
I have just been testing the solutions provided and have noted that none of them prevent access to a session belonging to the neighbouring app. Using different session identifier names with session_name() doesn't prevent users from using the value of these identifiers. PHP doesn't have a segregated storage for each session identifier name. I had two apps using different session names and setting a cookie path for the browser. The following respective Set-Cookie directives were included in HTTP responses:
Set-Cookie: TESTONE=<value one>; path=/testone/
Set-Cookie: TESTTWO=<value two>; path=/testtwo/
If both apps had entirely separate users and someone only had access to the /testtwo/ app, they may be able to access info on the /testone/ app depending on the way in which session parameters were being handled. An example code segment below shows a potential data breach assuming that both apps use a $_SESSION["authenticated"] parameter after successful authentication.
<?php
session_name("TESTONE");
ini_set("session.cookie_path","/testone/");
session_start();
if ($_SESSION["authenticated"] == "yes")
echo $topsecretinfo;
?>
To access this $topsecretinfo one would only need to authenticate on the /testtwo/ application, take the value of their TESTTWO session identifier and use it as the value of the TESTONE session identifier when sending requests to the /testone/ application. PHP's session lookup process does not recognise the name of the session identifier except for parsing the correspoding value. i.e. a session identifier value of "agcy648dja6syd8f93" will return the same session object regardless of the name used to refer to it.
You may be able to use session_set_cookie_params to set the domain and folder for the session to be saved under. IE:
// Used on foo.com/example
session_set_cookie_params(86400, '/example');
// Used on foo.com/bar
session_set_cookie_params(86400, '/bar');
You could also use the same session but change the variable names that you look for.
Edit: Sorry this doesn't answer your question but gives an alternative solution.
Another solution is to effectively create a namespace within your session by pre-pending all session values from foo.com/bar with "bar_" and foo.com/example with "example_".
The way you can keep this from being tedious is to abstract this functionality into a function or class method. For example:
function set_session_value($key, $value) {
//figure out which prefix to use by checking the current working
//directory, or whatever method you like. set $prefix equal to
// "bar_" or "example_".
$_SESSION[$prefix . $key] = $value;
}
Then get your values with a matching function.
The main advantage of this is that you don't have to think about what variable names you're using in /example while programming in /bar. The other is that if you decide to change how you are storing session values, you can easily change everything in one place.
I realize this is old, but thought it might help someone. This example shows how we are setting a separate session for our admin area.
if ( $_SERVER['REQUEST_URI'] == '/admin/' ):
$session_name = 'session1';
else:
$session_name = 'session2';
endif;
session_start( $session_name );
Related
I run a website which can be reached through different domains: domainname.de, domainname.ch, domainname.at, domainname.es etc. ...
When my customer wants to pay we gets to a payment page which is of course https secured. Due to server limitations I am only allowed to have one SSL Certificate which I only put on one domain: domainname-secure.com.
Because I charge different prices I need to know which domain the user belongs to, so when redirecting to domainname-secure.com I save the domain (e.g. domainname.de) in the session variable $_SESSION['domain_default'] and pass the sessionID by adding session_id=[session_id] as a get parameter.
Then I check I take $_GET['session_id'] and run the follow command to have the session available on the domainname-secure.com:
session_id($_GET['session_id']);
session_start();
When I test it myself, it works perfectly fine but I make a log entry when somebody gets to domainname-secure.com and has not have set $_SESSION['domain_default'].
This occurs several times a day but I really have no clue why this does not work! I am testing it again and again from many different links but for me it works perfectly fine.
Can some of you imagine why it sometimes does not work?
Is it not "good" or insecure to pass the session ID to another domain and is it not always readable after redirecting?
I know it is hard for you to determain a mistake but I am searching for some know issues with session or maybe a tip how to do it in a better way?
Session are administered by PHP on a per domain basis meaning they don't mix domains intentionally.
If you would be using another session storage mechanism such as writing into the database or using memcached sessions you'd be able to overcome this limitation.
There are two approaches if you want to be able to access the session info when changing domains either:
Don't use PHP's $_SESSION, setup your own session management with memcached/redis/sql;
Or:
Use PHP's $_SESSION, but when transferring from one domain to another serialize the data in $_SESSION and put it somewhere accessible from both domains like sql;
For example let's say I have an app that uses $_SESSION['user_id']. Now if I have two of these applications running on the same server then they will be sharing this user_id variable which would break things.
The only thing I can think of is to prepend some unique id like this:
$_SESSION['/app1/user_id']
$_SESSION['/app2/user_id']
is that the best option?
This is the purpose of session_name(). Assign a different name to each application's session to avoid collisions between $_SESSION keys. The name will be used as the session cookie's name so although both session cookies will be passed to both applications, only the one matching the application's session_name() will be used to populate $_SESSION.
// App 1
session_name('app1');
session_start();
// App 2
session_name('app2');
session_start();
I'm working on a project that keeps some user information (non-sensitive) in a php session. As it is my first time working with sessions, I never bothered to pass any Session ID, but it still works - is that right ? I couldn't find any information about that.
I'm using some parts of the information in the $_SESSION variable to navigate and influence some of the sites' behaviour, and it sometimes is crucial for the page to interact with the user. Meaning without the correct informatin of the current session the navigation will be broken.
So, can I rely on the existence of Sessions ?
And can I rely on the server to automatically pick the right session without passing the SID ?
I'm working only on one server and I don't need the session to be restorable (meaning that when a user leaves the application the session can be destroyed).
If you couldn't find information about that, you probably skipped the most obvious reference: the official PHP manual. It's right there in the Introduction of the Sessions chapter:
Session support in PHP consists of a way to preserve certain data
across subsequent accesses. This enables you to build more customized
applications and increase the appeal of your web site.
A visitor accessing your web site is assigned a unique id, the
so-called session id. This is either stored in a cookie on the user
side or is propagated in the URL.
If your question is whether cookies are reliable for this purpose, in fact it's the de-facto standard nowadays. You'll hardly find PHP-powered sites that still transmit the session ID in the URL. The reason is that it's a problematic technique: it's too easy to give away your session ID. If you copy the URL and send a link to a friend or post it in a forum it's very easy that any stranger is able to access your private data, even inadvertently (you don't need a malicious guy here) if they visit the site before the session has expired and the site does not implement further verifications (which is the usual situation).
Yes you can rely to having the server to pick the correct sessions for you. I have in my 10 years of php coding not experienced a faulty session yet.
However, if you choose to pass the sessionid to the next page, be ware of the risks. Session hijacking is a very serious business if you have any sort of private data.
I have few Facebook Apps hosted on a single domain on my server. It is possible that the same user may access two or more of my apps in a single session. How do I make sure that some data from one app doesn't end up in another app? Since the user may simply navigate away from the app, so logging out is not an option.
If you use a different session_name() for each app, the sessions are effectively inert from one another.
// Application 1
session_name("APP1");
session_start();
// Application 2
session_name("APP2");
session_start();
The solution I can think of would be including the application that the person is using in the session data, and if you see the wrong session in the user's session data, you destroy the session.
Just a thought: maybe you'd want to set up a subdomain for each one of your apps. That way the cookies and sessions are completely separate automatically, rather than relying on a function (which may be slow, as one person indicated in the session_name() manual comments.)
In addition, I believe separate subdomains keep you safer from exploits because of the same origin policy. (Right?)
You can make something like session sections by using different keys for every application. You just need to be sure to have the keys unique. Everytime you save some data into session save it in the proper section e.g.:
//save the ids into db or configuration file after it's generated
$app1id = uniqid('fbApp');
$app2id = uniqid('fbApp');
//Save data for application 1
$_SESSION[$app1id] = array('app' => 'data');
//Save data for application 2
$_SESSION[$app2id] = array('app' => 'data');
I am going to create a site that will have have multiple subdomains. For an example:
shop.domain.com
blog.domain.com
news.domain.com
account.domain.com
I would like to know if session variables can be passed between the subdomains. For an example $_SESSION['variable'] would be accessible on all of the subdomains listed above.
You first have to make sure to store session data in a way that all hosts can access them; if they are hosted on the same machine everything is fine, otherwise you might want to use another session handler which e.g. uses a database, memcache, ... to store session data.
Then you have to make sure the session id is available on all subdomains; this can be achieved by setting ini.session.cookie-domain.
For more information on sessions you should read the appropriate chapter in the fine php manual.