NYCPHP Meetup

NYPHP.org

[nycphp-talk] Experts help needed (Sessions)

Joseph Crawford codebowl at gmail.com
Tue Aug 2 09:32:39 EDT 2005


ok i now have another issue and thought i would seek help here once again ;)

the issue i am having is in the checkIP method, it checks the IP just fine 
and i had this working where it would delete the existing session and start 
a new one automatically however, if someone tried to hijack my session i 
wouldnt want to have to login all over again myself, i just want a new 
session started for the one who attempted to hijack my session.

i have tried to use output buffering with ob_start(); at the beginning of my 
file and ob_end_flush() at the end of my file, that doesnt seem to help with 
the error i am getting.

The following is the error i get 

*Warning*: session_regenerate_id() [function.session-regenerate-id]: Cannot 
send session cookie - headers already sent by (output started at 
E:\htdocs\csaf\test.php:10) in *E:\htdocs\csaf\lib\auth\session.php* on line 
*129*

the session id for the hijacker is never re-generated they continue to use 
the hijacked session id and it allows them to use the other person's 
session.

Worst case scenario is both users will have thier sessions reset by the 
script deleting the hijacked session from the database.

here is my code

<?php

class session
{
/* Define the mysql table you wish to use with
this class, this table MUST exist. */
private $table = "sessions";
private $_db;
private $_page;
private $_sess_id;
private $_ip;
private $_browser;
private $_browserList;
private $_os;
private $_osList;
static private $_type;
private $_typeIcon;


public function __construct(Database $db) {
$this->_db = $db;

$this->_browserList = array('offbyone' => 'ob1.gif', '3b_web' => '3b.gif', 
'getrig' => 'get.gif', 'webtv' => 'webtv.gif', 'aol' => 'aol.gif', 'opera' 
=> 'opera.gif', 'netposit' => 'netp.gif', 'ibrowse' => 'ibrowse.gif', 
'abrowse' => 'abrowse.gif', 'firefox' => 'firefox.gif', 'firebird' => '
firebird.gif', 'phoenix' => 'firebird.gif', 'omniweb' => 'omni.gif', 
'safari' => 'safari.gif', 'camino' => 'camino.gif', 'chimera' => 'camino.gif', 
'konqueror' => 'konq.gif', 'icab' => 'icab.gif', 'dillo' => 'dillo.gif', 
'epiphany' => 'epiph.gif', 'oregano' => 'oregano.gif', 'k-meleon' => '
kmel.gif', 'webcapture' => 'webcap.gif', 'galeon' => 'galeon.gif', 'lynx' => 
'lynx.gif', 'netscape' => 'netscape.gif', 'entergy' => 'entergy.gif', 'msie' 
=> 'ie.gif', 'mozilla' => 'moz.gif');
$this->_osList = array('linspire' => 'linspire.gif', 'lindows' => '
linspire.gif', 'beos' => 'beos.gif', 'skyos' => 'skyos.gif', 'atheos' => '
athe.gif', 'palmos' => 'palm.gif', 'nokia' => 'nokia.gif', 'blackberry' => '
blackb.gif', 'zeta' => 'zeta.gif', 'irix' => 'irix.gif', 'risc' => '
riscos.gif', 'os/2' => 'os2.gif', 'amigaos' => 'amiga.gif', 'freebsd' => '
fbsd.gif', 'netbsd' => 'nbsd.gif', 'sunos' => 'solaris.gif', 'solaris' => '
solaris.gif', 'os x' => 'osx.gif', 'osx' => 'osx.gif', 'darwin' => 'osx.gif', 
'macintosh' => 'macintosh.gif', 'mac_' => 'macintosh.gif', 'qnx' => 'qnx.gif', 
'linux' => 'linux.gif', 'unix' => 'unix.gif', 'x11' => 'x11.gif', 'windows' 
=> 'windows.gif', 'win95' => 'windows.gif', 'win98' => 'windows.gif', 
'winnt' => 'windows.gif');
self::setType();
}

private function init($ses_id) {
$this->_sess_id = $ses_id;
if(!isset($this->_page)) $this->_page = $_SERVER['REQUEST_URI'];
if(!isset($this->_ip)) $this->_ip = $_SERVER['REMOTE_ADDR'];
$this->setUserIcon();
if(!isset($this->_browser)) $this->setUserBrowser();
if(!isset($this->_os)) $this->setUserOS();

$this->CheckIP();
}

public function open($path, $name) {

return TRUE;
}

/* Close session */
public function close() {
/* This is used for a manual call of the
session gc function */
$this->gc(0);
return TRUE;
}

/* Read session data from database */
public function read($ses_id) {

$session_sql = "SELECT * FROM " . $this->table
. " WHERE ses_id = '$ses_id'";

$session_res = $this->_db->Query($session_sql);
if (!$session_res) {
return '';
}

$session_num = $this->_db->NumRows($session_res);
if ($session_num > 0) {
$session_row = $this->_db->FetchArray($session_res);
$ses_data = $session_row["ses_value"];
return $ses_data;
} else {
return '';
}
}

/* Write new data to database */
public function write($ses_id, $data) {
$session_sql = "SELECT * FROM ".$this->table." WHERE ses_id='".$ses_id."'";
$res = $this->_db->Query($session_sql);
$this->init($ses_id);
if( $this->_db->NumRows($res) == 0 ) {
$session_sql = "
INSERT INTO "
.$this->table." (ses_id, type, typeicon, ses_time, ses_start, page, ip, 
browser, os, ses_value)
VALUES 
('".$ses_id."', '".self::$_type."', '".$this->_typeIcon."', ".time().", 
".time().", '".$this->_page."', '".$this->_ip."', '".$this->_browser."', 
'".$this->_os."', '".$data."')";
} else {
$session_sql = "UPDATE ".$this->table." SET type='".self::$_type."', 
typeicon='".$this->_typeIcon."', ses_time=".time().", 
page='".$this->_page."', ses_value='".$data."' WHERE ses_id='".$ses_id."'";
}
echo $session_sql;
$session_res = $this->_db->Query($session_sql);
if (!$session_res) return FALSE;
else return TRUE;

}

/* Destroy session record in database */
public function destroy($ses_id) {
$session_sql = "DELETE FROM " . $this->table
. " WHERE ses_id = '$ses_id'";

$session_res = $this->_db->Query($session_sql);
if (!$session_res) return FALSE;
else return TRUE;
}

/* Garbage collection, deletes old sessions */
public function gc($life) {
$ses_life = strtotime("-5 minutes");

$session_sql = "DELETE FROM " . $this->table
. " WHERE ses_time < $ses_life";

$session_res = $this->_db->Query($session_sql);


if (!$session_res) return FALSE;
else return TRUE;
}

private function CheckIP() {
$res = $this->_db->Query("SELECT ip FROM ".$this->table." WHERE 
ses_id='".$this->_sess_id."'");
if($this->_db->NumRows($res) > 0) {
$data = $this->_db->FetchArray($res);
echo $data['ip'].'<br>';
echo $_SERVER['REMOTE_ADDR'];
if( strcmp($data['ip'], $_SERVER['REMOTE_ADDR']) != 0 ) {
echo 'YOU HAVE HIJACKED A SESSION, SESSION DESTROYED!';
//$sess_sql = "DELETE FROM ".$this->table." WHERE 
ses_id='".$this->_sess_id."'";
//$this->_db->Query($sess_sql);
$this->_sess_id = session_regenerate_id();
echo $this->_sess_id;
}
}
}

private function setUserIcon() {
switch(self::$_type) {
case 'AD':
$this->_typeIcon .= 'images/icons/user/admin.png';
break;
case 'CL':
$this->_typeIcon .= 'images/icons/user/client.png';
break;
case 'CO':
$this->_typeIcon .= 'images/icons/user/contractor.png';
break;
default:
$this->_typeIcon .= 'images/icons/user/guest.png';
}
}

private function setUserBrowser() {
foreach ($this->_browserList as $browser => $img) {
if(stristr($_SERVER['HTTP_USER_AGENT'], $browser)) {
$this->_browser .= 'images/icons/browser/'.$img;
break;
}
}
}

private function setUserOS() {
foreach ($this->_osList as $os => $img) {
if(stristr($_SERVER['HTTP_USER_AGENT'], $os)) {
$this->_os .= 'images/icons/os/'.$img;
break;
}
}
}

static public function setType( $type = 'GU' ) {
$type = substr($type, 0, 2);
if(isset($type) && is_string($type) && strlen($type) == 2) self::$_type = 
strtoupper($type);
}
}
?>

On 8/1/05, Joseph Crawford <codebowl at gmail.com> wrote:
> 
> Anyone ever seen this error?
> 
> *Fatal error*: Exception thrown without a stack frame in *Unknown* on line 
> *0*
> 
> *Warning*: Unknown: A session is active. You cannot change the session 
> module's ini settings at this time. in *Unknown* on line *0*
> 
> -- 
> Joseph Crawford Jr.
> Codebowl Solutions, Inc. 
> 1-802-671-2021
> codebowl at gmail.com 
> 



-- 
Joseph Crawford Jr.
Codebowl Solutions, Inc.
1-802-671-2021
codebowl at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.nyphp.org/pipermail/talk/attachments/20050802/4cedc5b8/attachment.html>


More information about the talk mailing list