Solved

disappearing session cookie with IP based address

Posted on 2006-07-09
15
331 Views
Last Modified: 2012-08-13
Running PHP 4.3.x

I have a get_host() function that returns the host name to use when setting cookies. Recently I wanted to modify it to handle IP based addresses and encountered some problems. I think the sample scripts below illustrate the problem pretty well. If you run the scripts with domain based addressing (i.e. "http://www.yourdomain.com/test1.php"), then everything works fine. If you run the scripts with IP based addressing (i.e. "http://12.34.56.78/test1.php") and click the "again with ip mode?" link, the session cookie is unavailable to test2.php. Why? How to fix?

This is taken from a login page that needs to authorize a user and redirect them to a restricted area.

file 1: "test1.php"
--------------------------
<?php

/*
start with a routine to kill existing session and start session over (this
is from a login page). if $_GET['mode'] is not set to "ip" when running with
an IP based address, then get_host() returns a truncated host name (i.e. ".12.34"),
which I'm pretty sure means the browser won't accept the setcookie() call.

If $_GET['mode'] is set to "ip" when running with
an IP based address, then full IP is returned by get_host, and setcookie()
call should work, with browser accepting cookie.
*/
if (!session_id())  session_start();
foreach ($_SESSION as $key => $value)  $_SESSION[$key] = '';
$host = get_host();
setcookie(session_name(),'',time()-86400,"/", $host, 0);
session_destroy();

session_start();

$msg = "host used='$host'<br />";
$msg .= "session_id on test1 was '".session_id()."'";

$redirect = 'http://'.$_SERVER['HTTP_HOST'].substr(dirname($_SERVER['SCRIPT_NAME']), 1)."/test2.php?msg=".urlencode($msg);

header('Location: '.$redirect);

function get_host()            ## $host used for setting cookies
{
      preg_match('/^(([A-Z0-9][A-Z0-9_-]*\.)*([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)/i', $_SERVER['SERVER_NAME'], $matches);
      if ($_GET['mode'] == 'ip')
      {
            if (is_numeric($matches[4]))  $host = $matches[0];            ## if $matches[4] is numeric, then host is IP
            else $host = '.'.$matches[3].$matches[4];
      } else $host = '.'.$matches[3].$matches[4];

      return $host;
}

?>
--------------------------



file 2: "test2.php"
--------------------------
<?php

if (!session_id())  session_start();

require_once($_SERVER['DOCUMENT_ROOT'].'/pointer_config.php');

if ($_GET['msg'])  $msg = urldecode($_GET['msg']);
echo $msg.'<br /><br />';

echo 'session_id='.session_id().'<br />';
echo '$_COOKIE['.session_name().']='.$_COOKIE[session_name()].'<br />';

echo '<br /><b>COOKIE VARS:</b><br>';
foreach ($_COOKIE as $key => $value)  echo $key.'='.$value.'<br>';

/*
the following links get session identifier added to them when running with
an IP based address, mode=ip, and -enable-trans-sid = 1, indicating that
server suddenly thinks browser is not accepting cookies.
*/
echo '<br /><br /><a href="test1.php">again?</a>';
echo '<br /><a href="test1.php?mode=ip">again with ip mode?</a>';
exit;

?>
--------------------------
0
Comment
Question by:merwetta1
  • 7
  • 6
15 Comments
 
LVL 6

Author Comment

by:merwetta1
ID: 17069499
this line in test2.php:
require_once($_SERVER['DOCUMENT_ROOT'].'/pointer_config.php');
is extraneous and doesn't need to be there
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069639
sessions are recognized using cookies

your browser should make a new cookie for a 'new' address, as to the browser the IP address is different to the DNS address

so you have to pass the session as a variable to the IP mode.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069661
im not sure if this would work but setting the

session_id($id) might make php use the session of the dns site when going to the ip site..as long as you dont close the session

--

otherwise you can use session_encode and send that as a string (through get) to the ip mode and decode it on the otherside
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17069692
maUru, thanks for the response. I'm not trying to go from the domain to the IP, but just having problems when doing this all by IP. If you run the 2 files I provided using IP based addressing, when you click the "again with ip mode?" link, you should see that the session cookie has disappeared. I'm looking for an explanation of that.

I think any expert that wants to answer this question should try running the files to see what I'm talking about.
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17069704
so if you run these scripts with IP addressing, when you first pull it up and when you click "try again", you see the session cookie is fine. when you click "try again with ip mode", the session cookie is gone. The only difference between the two is in the host used by setcookie(). why does one show the session cookie and the other not?
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069738
ah i see the problem

but then what is the point of ipmode, i mean removing this:

     preg_match('/^(([A-Z0-9][A-Z0-9_-]*\.)*([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)/i', $_SERVER['SERVER_NAME'], $matches);

     if ($_GET['mode'] == 'ip')
     {
          if (is_numeric($matches[4]))  $host = $matches[0];          ## if $matches[4] is numeric, then host is IP
          else $host = '.'.$matches[3].$matches[4];
     } else

makes it work.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069746
my bad, was looking at wrong host
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 6

Author Comment

by:merwetta1
ID: 17069812
if $_GET['mode'] is not set to "ip" when running with an IP based address, then get_host() returns a truncated host name (i.e. ".12.34"), which I'm pretty sure means the browser won't clear the session cookie with the setcookie() call.

So in other words, without the mode=ip stuff, the session cookie never gets cleared in test1.php, which is not desirable, but cookies work fine after redirect to test2.php.

If $_GET['mode'] is set to "ip" when running with an IP based address, then full IP is returned by get_host, and session cookie is cleared by test1.php, but then PHP acts like cookies are disabled after redirect to test2.php.

Clearing the session cookie is having an adverse effect, but only with IP based addressing, and I want to understand why only with IP based addressing.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069833
well even without IP mode, you are not setting the domain .bla.com for example

did you write this code or did you extract it from somewhere and try to manipulate it?
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17069881
>well even without IP mode, you are not setting the domain .bla.com for example

not sure why you say that. when i run test1.php as http://www.mydomain.com/test1.php, the first line says:   host used='.mydomain.com'

the code is extracted from a login script I wrote myself.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069907
yes but the host used that you are echoing is from a function that removes the 3rd 4th tier of the domain

BUT

it is not actually being used anywhere, its not actually getting assigned to the PHPSESSID cookie, in fact, your PHPSESSID cookie (the setcookie line) is not even writing the session_id, so as far as this code is concerned, the host manipulation is redundant

if you could just explain what you are trying to do, i can give you a solution.
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17070352
the host being echoed is used in this line:
setcookie(session_name(),'',time()-86400,"/", $host, 0);

I am executing that line because it's a good idea to clear the session cookie per
http://us2.php.net/manual/en/function.session-destroy.php

I use the get_host function to truncate the host to ".domain.com" because if a customer enters the site as "domain.com" and gets linked to "www.domain.com" somewhere along the line (or maybe it's vice versa?), cookies will not be available. This is my fix to a recurring problem of cookies only being available to subdomains.

I think it's reasonable to expect that my get_host() function would return the correct host string that the session cookie is using, and looking at the cookies confirms that. This routine has been working for a long time at a lot of sites not using IP based addressing. Now I want it to work with IP addresses, too. Because a lot of sites are depending on the routine, I can't just start from scratch.

Can you confirm that when you run the scripts under a domain name, ip mode shows the session cookie and when you run them under an IP address, ip mode loses the session cookie?
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17070418
I changed one line in the get_host function and now it works perfectly.

if (is_numeric($matches[4]))  $host = '/';            ## if $matches[4] is numeric, then host is IP

So I revert to using "/" as the host, but only for IP based addresses. I'm guessing it's not right to pass an IP as the host in setcookie(). Problem solved.
0
 
LVL 5

Accepted Solution

by:
Netminder earned 0 total points
ID: 17118244
Closed, 500 points refunded.
Netminder
Site Admin
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Deprecated and Headed for the Dustbin By now, you have probably heard that some PHP features, while convenient, can also cause PHP security problems.  This article discusses one of those, called register_globals.  It is a thing you do not want.  …
Introduction This article is intended for those who are new to PHP error handling (https://www.experts-exchange.com/articles/11769/And-by-the-way-I-am-New-to-PHP.html).  It addresses one of the most common problems that plague beginning PHP develop…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now