session management: vulnerability and bug

ale2005
ale2005's picture

Joined: 2005-01-27
Posts: 4
Posted: Fri, 2005-02-04 08:37

The vulnerability is well described in
http://www.acros.si/papers/session_fixation.pdf

The bug is the session name: the cookie name is the default
PHPSESSID whilst what is being set is the name of the variable
internally stored. Making an MD5 for that variable's name is
completely nonsensical, AFAICS. Also, session_id()
will never return an id before the session starts...

I have fixed some of that, and I attach a (zipped) session.php.
That code works for me, but it requires some relatively
recent PHP version (PHP 4 >= 4.3.2, PHP 5).

The function defined there should be called on login.php (and
the protocol handlers?) and command-logout before starting
output
, so that the new cookie name can be set in the
header.

AttachmentSize
session.zip1.75 KB
 
bharat
bharat's picture

Joined: 2002-05-21
Posts: 7994
Posted: Fri, 2005-02-04 10:29

This does look like something that we can readily address in 1.5 and the upcoming 1.4.4 patch release. Thanks for pointing it out. I'll ask Signe to follow up here.

A few points:
* We call session_id() before session_start() because we may already be embedded inside a CMS which has started a session for us.
* Calling md5() on the session variable's name gives us a fixed length (32 character) variable name with an incredibly low chance of collision.
* We can't use session_regenerate_id() since we're backwards compatible to PHP 4.1.0. We can implement our own, though (there's a sample version in the notes on http://php.net/session_regenerate_id)

 
ale2005
ale2005's picture

Joined: 2005-01-27
Posts: 4
Posted: Fri, 2005-02-04 18:01


Sorry, I didn't consider CMS... Anyway, to fix the vulnerability when
under CMS would require its cooperation, IMHO.

bharat wrote:
...
* We call session_id() before session_start() because we may already be embedded inside a CMS which has started a session for us.

I see. Then the session_start() below just causes an error
(A session had already been started).

bharat wrote:
...
* Calling md5() on the session variable's name gives us a fixed length (32 character) variable name with an incredibly low chance of collision.

I must understand you mean collision with some CMS variable.
It may make sense to only do that if inside CMS, and otherwise
set our own cookie name. E.g.

$gSessionName = $gallery->app->sessionVar;
if (empty($gSessionName)) $gSessionVar = "GALLERY_SESS";
if (session_id()) {
  $gSessionVar = sprintf("%s_%s", $gSessionName, md5(getcwd()));
  £useStdClass = 1;
} else {
  session_name($gSessionName);
  $gSessionVar = $gSessionName;
  session_start();
}

If not, one cannot run more than one gallery under the same host,
because the session names will collide.

bharat wrote:
* We can't use session_regenerate_id() since we're backwards compatible to PHP 4.1.0. We can implement our own, though (there's a sample version in the notes on http://php.net/session_regenerate_id

Yup, that emulates session_regenerate_id to the point that both don't
delete the file (perhaps CMS sets another handler?). The cookie call
at the end should be

        setcookie(session_name(), session_id(), NULL, '/');

in case the cookie name changed.

 
signe
signe's picture

Joined: 2003-07-27
Posts: 2322
Posted: Fri, 2005-02-18 06:45

ale2005, I just wanted to let you know that I've checked in fixes for this issue. I opted for an approach that's similar to yours, however not identical... feel free to give us some feedback on it, if you'd like.