note 72856 deleted from ref.session by didou

From: Date: Sat, 03 Feb 2007 15:00:52 +0000
Subject: note 72856 deleted from ref.session by didou
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-122667@lists.php.net to get a copy of this message
Note Submitter: nihato at notrashplease dot taakc dot org ---- I am truly sorry for asking a question here. I tried the newgroups that the support page points to; the last date of activity there appears to be sometime in 2004. Another excuse: in the case my problem is a stupid one with a trivial solution, then this post can potentially belong in here. So, here it goes. I am new to PHP, but not a novice programmer. What I want is a simple, textbook defense against session fixation/hijacking threat. I am looking at Marc Wandschneider's book (Web App Development /w PHP & MySQL, pgs. 647+). The code in simplified form is as follows (/w comments): <?php session_start(); // Ensure that you created the session. I.e., if ( !isset($_SESSION['created']) ) { session_regenerate_id(); $_SESSION['created'] = TRUE; $_SESSION['page_i_Cnt'] = 0; // see below; i = 1, 2, ... } // If compromised, make the attacker's life more difficult. I.e., if ( !isset($_SESSION['userAgent']) ) { $_SESSION['userAgent'] = md5("SomeSalt" . $_SERVER['HTTP_USER_AGENT']); // Added some salt and hashed it. Hashing alone is not good enough since // the attacker can guess and inject typical user agents. } else { if ( $_SESSION['userAgent'] != md5("SomeSalt" . $_SERVER['HTTP_USER_AGENT']) ) $_SESSION['compromised'] = TRUE; // So, the attacker is caught red-handed although he has captured the session id. // Do something appropriate: refuse to continue. } ?> Now, this didn't work for me. I tried this using IE6 and FF browsers. I am not showing the test pages for brevity, but they are trivial; a couple of pages linking to one another, each counting how many times they are visited. The counters are initialized in the first if block as shown above, and each test page increments its counter after "requiring once" the above prelude. That is, their very first line is like: <?php require_once('session.inc'); ++$_SESSION['page_1_Cnt']; ?> The outcome of the above code is, the counts are not properly maintained: the present page shows a count of 1, the others 0, always, consistently. Upon closer examination, I found that the first "regenerate_id" block was entered on each page visit. So, instead of two data storage files per session, I was getting one file per click (page visit): no passing of session data from one page to the next as intended. I tweaked the code quite a bit (built it up piece by piece from nothing, and stripped it down to bare bones), and found that it would work properly only if the reference to HTTP_USER_AGENT in the _SERVER array was eliminated. To be sure, I tried this most innocent version: <?php $str = $_SERVER['HTTP_USER_AGENT']; // Just a meaningless reference to _SERVER array session_start(); if ( !isset($_SESSION['created']) ) { session_regenerate_id(); $_SESSION['created'] = TRUE; $_SESSION['page_i_Cnt'] = 0; // see below; i = 1, 2, ... } ?> Even that didn't work. Take out that reference, it works. I am totally mystified. Any clue/input will be appreciated. I am willing to edit and repost this as usable snippet if I can find a solution. Thanks in advance. Nihat

« previous php.notes (#122667) next »