richter     00/11/09 00:03:16

  Modified:    .        Embperl.pm epmain.c test.pl
               Embperl  Session.pm
               test/cmp delsess.htm
               test/html delsess.htm
  Added:       test/cmp delwrsess.htm
               test/html delwrsess.htm setbadsess.htm setunknownsess.htm
  Log:
  Session Managenet enhanements
  
  Revision  Changes    Path
  1.125     +28 -39    embperl/Embperl.pm
  
  Index: Embperl.pm
  ===================================================================
  RCS file: /home/cvs/embperl/Embperl.pm,v
  retrieving revision 1.124
  retrieving revision 1.125
  diff -u -r1.124 -r1.125
  --- Embperl.pm        2000/11/08 07:49:07     1.124
  +++ Embperl.pm        2000/11/09 08:03:14     1.125
  @@ -10,7 +10,7 @@
   #   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
   #   WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   #
  -#   $Id: Embperl.pm,v 1.124 2000/11/08 07:49:07 richter Exp $
  +#   $Id: Embperl.pm,v 1.125 2000/11/09 08:03:14 richter Exp $
   #
   ###################################################################################
   
  @@ -405,8 +405,8 @@
           eval "require $session_handler" ; 
           die $@ if ($@)  ;
   
  -     tie %udat, $session_handler, undef, \%sargs ;
  -     tie %mdat, $session_handler, undef, \%sargs ;
  +     tie %mdat, $session_handler, undef, \%sargs ;
  +     tie %udat, $session_handler, undef, {%sargs, recreate_id => 1} ;
        $SessionMgnt = 2 ;
        warn "[$$]SES:  Embperl Session management enabled ($ver)\n" if 
($ENV{MOD_PERL}) ;
           }
  @@ -425,32 +425,9 @@
           }
       }
   
  
-#######################################################################################
  -
  -#no strict ;
  -
  -sub _eval_ ($)
  -    {
  -    my $result = eval "package $evalpackage ; $_[0] " ;
  -    if ($@ ne '')
  -        { logevalerr ($@) ; }
  -    return $result ;
  -    }
   
  -#use strict ;
  -
   
#######################################################################################
   
  -sub _evalsub_ ($)
  -    {
  -    my $result = eval "package $evalpackage ; sub { $_[0] } " ;
  -    if ($@ ne '')
  -        { logevalerr ($@) ; }
  -    return $result ;
  -    }
  -
  
-#######################################################################################
  -
   sub Warn 
       {
       local $^W = 0 ;
  @@ -1647,8 +1624,6 @@
            {
            $sessid = $1 ;
            print HTML::Embperl::LOG "[$$]SES:  Received session cookie $1\n" if 
($HTML::Embperl::dbgSession) ;
  -            
  -            $r -> SessionMgnt (0) if ($r) ; # do not resend cookie
               }
   
        if ($HTML::Embperl::SessionMgnt == 1)
  @@ -1711,8 +1686,14 @@
       my $r = shift || HTML::Embperl::CurrReq () ;
       my $disabledelete = shift ;
   
  -    tied(%HTML::Embperl::udat) -> delete if (!$disabledelete) ; # Delete session 
data
  -    $r -> SessionMgnt (-1) ; # resend cookie without value
  +    if (!$disabledelete)  # Delete session data
  +        {
  +        tied(%HTML::Embperl::udat) -> delete ;
  +        }
  +    else
  +        {
  +        tied (%HTML::Embperl::udat) -> setid (undef) ; # for make test only
  +        }
       }
   
   
  @@ -1723,7 +1704,7 @@
       {
       my $r = shift || HTML::Embperl::CurrReq () ;
   
  -    $r -> SessionMgnt ($HTML::Embperl::SessionMgnt) ; # resend cookie 
  +    $r -> SessionMgnt ($HTML::Embperl::SessionMgnt | 4) ; # resend cookie 
       }
   
   
#######################################################################################
  @@ -1739,7 +1720,7 @@
        my $udat = tied(%HTML::Embperl::udat) ;
        my $mdat = tied(%HTML::Embperl::mdat) ;
   
  -     if ($HTML::Embperl::SessionMgnt == 1)
  +     if ($HTML::Embperl::SessionMgnt & 1)
            {
            if ($udat->{'DIRTY'})
                {
  @@ -1779,14 +1760,22 @@
       my $r = shift ;
       $r = undef if (!(ref ($r) =~ /^HTML::Embperl/));
   
  -    if ($HTML::Embperl::SessionMgnt && (!defined ($r) || $r -> SessionMgnt))
  +    if ($HTML::Embperl::SessionMgnt)
           {
  -        my $name   = $ENV{EMBPERL_COOKIE_NAME} || 'EMBPERL_UID' ;
  -        my $domain = "; domain=$ENV{EMBPERL_COOKIE_DOMAIN}" if (exists 
($ENV{EMBPERL_COOKIE_DOMAIN})) ;
  -        my $path   = "; path=$ENV{EMBPERL_COOKIE_PATH}" if (exists 
($ENV{EMBPERL_COOKIE_PATH})) ;
  -        my $expires = "; expires=$ENV{EMBPERL_COOKIE_EXPIRES}" if (exists 
($ENV{EMBPERL_COOKIE_EXPIRES})) ;
  -    
  -        Apache -> request -> header_out ("Set-Cookie" => "$name=" . (tied 
(%HTML::Embperl::udat) -> getid). "$domain$path$expires") ;
  +        my $udat   = tied (%HTML::Embperl::udat) ;
  +        my $id     = $udat -> getid ;
  +        my $initialid     = $udat -> getinitialid ;
  +        
  +        my $name   = $ENV{EMBPERL_COOKIE_NAME} || 'EMBPERL_UID' ;
  +        my $domain = "; domain=$ENV{EMBPERL_COOKIE_DOMAIN}" if (exists 
($ENV{EMBPERL_COOKIE_DOMAIN})) ;
  +        my $path   = "; path=$ENV{EMBPERL_COOKIE_PATH}" if (exists 
($ENV{EMBPERL_COOKIE_PATH})) ;
  +        my $expires = "; expires=$ENV{EMBPERL_COOKIE_EXPIRES}" if (exists 
($ENV{EMBPERL_COOKIE_EXPIRES})) ;
  +        $expires = "; expires=Thu, 1-Jan-1970 00:00:01 GMT" if ($id && !$initialid) 
;
  +                        
  +        if ($id || $initialid)
  +            {    
  +            Apache -> request -> header_out ("Set-Cookie" => 
"$name=$id$domain$path$expires") ;
  +            }
           }
       }
   
  
  
  
  1.83      +38 -33    embperl/epmain.c
  
  Index: epmain.c
  ===================================================================
  RCS file: /home/cvs/embperl/epmain.c,v
  retrieving revision 1.82
  retrieving revision 1.83
  diff -u -r1.82 -r1.83
  --- epmain.c  2000/11/08 07:49:09     1.82
  +++ epmain.c  2000/11/09 08:03:14     1.83
  @@ -2556,12 +2556,46 @@
            SV **   ppSVID ;
            SV *    pSVID = NULL ;
               MAGIC * pMG ;
  -         char *  pUID = NULL ;
  -         STRLEN  ulen = 0 ;
  +         char *  pUID = NULL ;
  +         char *  pInitialUID = NULL ;
  +         STRLEN  ulen = 0 ;
  +         STRLEN  ilen = 0 ;
   
            if (r -> nSessionMgnt)
                {                       
  -             if (r -> nSessionMgnt == -1)
  +             SV * pUserHashObj = NULL ;
  +             if ((pMG = mg_find((SV *)r -> pUserHash,'P')))
  +                 {
  +                 dSP;                            /* initialize stack pointer      
*/
  +                 int n ;
  +                 pUserHashObj = pMG -> mg_obj ;
  +
  +                 PUSHMARK(sp);                   /* remember the stack pointer    
*/
  +                 XPUSHs(pUserHashObj) ;            /* push pointer to obeject */
  +                 PUTBACK;
  +                 n = perl_call_method ("getinitialid", 0) ; /* call the function    
         */
  +                 SPAGAIN;
  +                 if (n > 0)
  +                     {
  +                     pSVID = POPs;
  +                     pInitialUID = SvPV (pSVID, ilen) ;
  +                     }
  +                 PUTBACK;
  +
  +                 PUSHMARK(sp);                   /* remember the stack pointer    
*/
  +                 XPUSHs(pUserHashObj) ;            /* push pointer to obeject */
  +                 PUTBACK;
  +                 n = perl_call_method ("getid", 0) ; /* call the function           
  */
  +                 SPAGAIN;
  +                 if (n > 0)
  +                     {
  +                     pSVID = POPs;
  +                     pUID = SvPV (pSVID, ulen) ;
  +                     }
  +                 PUTBACK;
  +                 }
  +             
  +             if (ilen > 0 && ulen == 0)
                    { /* delete cookie */
                    pCookie = newSVpvf ("%s=; expires=Thu, 1-Jan-1970 00:00:01 
GMT%s%s%s%s",  r -> pConf -> sCookieName, 
                                r -> pConf -> sCookieDomain[0]?"; domain=":""  , r -> 
pConf -> sCookieDomain, 
  @@ -2570,36 +2604,7 @@
                    if (r -> bDebug & dbgSession)  
                        lprintf (r, "[%d]SES:  Delete Cookie -> %s\n", r -> nPid, 
SvPV(pCookie, ldummy)) ;
                    }
  -             else if (r -> nSessionMgnt == 2)
  -                 {                   
  -                 if ((pMG = mg_find((SV *)r -> pUserHash,'P')))
  -                     {
  -                     dSP;                            /* initialize stack pointer    
  */
  -                     SV * pUserHashObj = pMG -> mg_obj ;
  -                     int n ;
  -
  -
  -                     PUSHMARK(sp);                   /* remember the stack pointer  
  */
  -                     XPUSHs(pUserHashObj) ;            /* push pointer to obeject */
  -                     PUTBACK;
  -                     n = perl_call_method ("getid", 0) ; /* call the function       
      */
  -                     SPAGAIN;
  -                     if (n > 0)
  -                         {
  -                         pSVID = POPs;
  -                         pUID = SvPV (pSVID, ulen) ;
  -                         }
  -                     PUTBACK;
  -                     }
  -                 }
  -             else
  -                 {
  -                 ppSVID = hv_fetch (r -> pUserHash, sUIDName, sizeof (sUIDName) - 
1, 0) ;
  -                 if (ppSVID && *ppSVID)
  -                     pUID = SvPV (*ppSVID, ulen) ;
  -                 }
  -         
  -             if (ulen > 0)
  +             else if (ulen > 0 && ilen == 0 || (r -> nSessionMgnt & 4))
                    {
                    pCookie = newSVpvf ("%s=%s%s%s%s%s%s%s",  r -> pConf -> 
sCookieName, pUID,
                                r -> pConf -> sCookieDomain[0]?"; domain=":""  , r -> 
pConf -> sCookieDomain, 
  
  
  
  1.78      +27 -2     embperl/test.pl
  
  Index: test.pl
  ===================================================================
  RCS file: /home/cvs/embperl/test.pl,v
  retrieving revision 1.77
  retrieving revision 1.78
  diff -u -r1.77 -r1.78
  --- test.pl   2000/11/07 19:05:05     1.77
  +++ test.pl   2000/11/09 08:03:15     1.78
  @@ -341,6 +341,12 @@
       'getsess.htm' => {
           'offline'    => 0,
           },
  +    'delwrsess.htm' => { 
  +        'offline'    => 0,
  +        },
  +    'getsess.htm' => {
  +        'offline'    => 0,
  +        },
       'delsess.htm' => { 
           'offline'    => 0,
           },
  @@ -350,6 +356,14 @@
       'clearsess.htm' => {
           'offline'    => 0,
           },
  +    'setbadsess.htm' => { 
  +        'offline'    => 0,
  +        'query_info' => 'val=2&cookie=/etc/passwd',
  +        },
  +    'setunknownsess.htm' => { 
  +        'offline'    => 0,
  +        'query_info' => 'val=3&cookie=1234567890abcdefABCDEF',
  +        },
       'EmbperlObject/epopage1.htm' => {
           'offline'    => 0,
           'cgi'        => 0,
  @@ -743,14 +757,22 @@
       my $ua = new LWP::UserAgent;    # create a useragent to test
   
       my($request,$response,$url);
  +    my $cookiesend  ;
   
  -
       if (!$upload)
        {
        $url = new URI::URL("http://$host:$port/$loc/$file?$query");
   
        $request = new HTTP::Request($content?'POST':'GET', $url);
  -        $request -> header ('Cookie' => $cookie) if ($cookie && !($query =~ 
/nocookie/)) ;
  +        if ($query =~ /cookie=(.*?)$/)
  +            {
  +            $request -> header ('Cookie' => $1) ;
  +            $cookiesend = $1 ;
  +            }
  +        else
  +            {             
  +            $request -> header ('Cookie' => $cookie) if ($cookie && !($query =~ 
/nocookie/)) ;
  +            }
           
        $request -> content ($content) if ($content) ;
        }
  @@ -781,6 +803,8 @@
       $cookie = undef if (($c =~ /EMBPERL_UID=;/)) ;  
       #print "Got Cookie $cookie\n" ;
   
  +    print "Expected new cookie: Send $sendcookie, Got: $cookie\n" if ($sendcookie 
&& $sendcookie eq $cookie) ;
  +    
       #print $response -> headers -> as_string () ;
   
       return $response -> message if (!$response->is_success) ;
  @@ -927,6 +951,7 @@
           { $opt_modperl = $opt_cgi = $opt_offline = $opt_execute = 1 }
       else
           { $opt_offline = $opt_execute = 1 }
  +    $opt_ep1 = 1 ;
       }
   
   
  
  
  
  1.6       +67 -23    embperl/Embperl/Session.pm
  
  Index: Session.pm
  ===================================================================
  RCS file: /home/cvs/embperl/Embperl/Session.pm,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Session.pm        2000/11/07 11:28:27     1.5
  +++ Session.pm        2000/11/09 08:03:15     1.6
  @@ -32,8 +32,14 @@
   =item create_unknown
   
   Setting this to one causes Apache::Session to create a new session
  +with the given id (or a new id, depending on C<recreate_id>)
   when the specified session id does not exists. Otherwise it will die.
   
  +=item recreate_id
  +
  +Setting this to one causes Apache::Session to create a new session id
  +when the specified session id does not exists. 
  +
   =item object_store
   
   Specify the class for the object store. (The Apache::Session:: prefix is
  @@ -148,7 +154,8 @@
       my $self = 
           {
           args         => $args,
  -        data         => { _session_id => $session_id },
  +        data         => { _session_id => $session_id },
  +        initial_session_id => $session_id,
           lock         => 0,
           lock_manager => undef,
           object_store => undef,
  @@ -236,30 +243,39 @@
   
       if (defined $session_id  && $session_id) 
           {
  -        if (exists $self -> {'args'}->{Transaction} && $self -> 
{'args'}->{Transaction}) 
  -            {
  -            $self->acquire_write_lock;
  -            }
  +        #check the session ID for remote exploitation attempts
  +        #this will die() on suspicious session IDs.        
  +
  +        eval { &{$self->{validate}}($self); } ;
  +        if (!$@)
  +            { # session id is ok        
  +            if (exists $self -> {'args'}->{Transaction} && $self -> 
{'args'}->{Transaction}) 
  +                {
  +                $self->acquire_write_lock;
  +                }
   
  -        $self->{status} &= ($self->{status} ^ NEW);
  +            $self->{status} &= ($self->{status} ^ NEW);
   
  -     if ($self -> {'args'}{'create_unknown'})
  -         {
  -            eval { $self -> restore } ;
  -         #warn "Try to load session: $@" if ($@) ;
  -         $@ = "" ;
  -         $session_id = $self->{data}->{_session_id} ;
  -         }
  -     else
  -         {
  -         $self->restore;
  -         }
  -        }
  +         if ($self -> {'args'}{'create_unknown'})
  +             {
  +                eval { $self -> restore } ;
  +             #warn "Try to load session: $@" if ($@) ;
  +             $@ = "" ;
  +             $session_id = $self->{data}->{_session_id} ;
  +             }
  +         else
  +             {
  +             $self->restore;
  +             }
  +            }
  +        }
   
  +    $@ = '' ;
  +
       if (!($self->{status} & SYNCED))
           {
           $self->{status} |= NEW();
  -        if (!$self->{data}->{_session_id})
  +        if (!$self->{data}->{_session_id} || $self -> {'args'}{'recreate_id'})
               {
               if (exists ($self->{generate}))
                   { # Apache::Session >= 1.50
  @@ -391,9 +407,15 @@
   sub getid {
       my $self = shift;
   
  -    return $self->{data}->{_session_id} ;
  +    return $self->{data}->{_session_id} || $self->{'ID'} ;
   }
   
  +sub getinitialid {
  +    my $self = shift;
  +
  +    return $self->{initial_session_id} ;
  +}
  +
   sub delete {
       my $self = shift;
       
  @@ -402,7 +424,8 @@
       $self -> init if (!$self -> {'status'}) ;
   
       $self->{status} |= DELETED;
  -    $self->save;
  +    $self->save;
  +    $self->{data} = {} ; # Throw away the data
   }    
   
   
  @@ -422,6 +445,21 @@
       return new {$self -> {'args'}{'lock_manager'}} $self;
   }
   
  +#
  +# Default validate for Apache::Session < 1.53
  +#
  +
  +sub validate {
  +    #This routine checks to ensure that the session ID is in the form
  +    #we expect.  This must be called before we start diddling around
  +    #in the database or the disk.
  +
  +    my $session = shift;
  +    
  +    if ($session->{data}->{_session_id} !~ /^[a-fA-F0-9]+$/) {
  +        die;
  +    }
  +}
   
   #
   # For Apache::Session >= 1.50
  @@ -439,10 +477,16 @@
   
       $self->{object_store} = new $store $self if ($store) ;
       $self->{lock_manager} = new $lock $self if ($lock);
  -    $self->{generate}     = \&{$gen . '::generate'} if ($gen);
  +    $self->{generate}     = \&{$gen . '::generate'} if ($gen);
  +    $self->{validate}     = \&{$gen . '::validate'} if ($gen && defined (&{$gen . 
'::validate'}));
       $self->{serialize}    = \&{$ser . '::serialize'} if ($ser);
       $self->{unserialize}  = \&{$ser . '::unserialize'} if ($ser) ;
  -
  +
  +    if (!defined ($self->{validate}))
  +        {
  +        $self->{validate} = \&validate ;
  +        }
  +
       return $self;
       }
   
  
  
  
  1.3       +3 -12     embperl/test/cmp/delsess.htm
  
  Index: delsess.htm
  ===================================================================
  RCS file: /home/cvs/embperl/test/cmp/delsess.htm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- delsess.htm       2000/09/11 09:53:33     1.2
  +++ delsess.htm       2000/11/09 08:03:15     1.3
  @@ -13,20 +13,11 @@
                </tr>
        </table>
   
  -^    ok \(num=\d+\)<p>
  +     ok (num=1)<p>
   
       $mdat{cnt} = -- <br>
       $udat{cnt} = -- <br>
   
  -     udat after:<br>
  -     <table>
  -             <tr>
  -                     <td>a</td><td>1</td>
  -             </tr>
  -     </table>
  -
  -^    ok \(num=\d+\)<p>
  -
  -</body>
  +     </body>
   </html>
  -
  +
  
  
  
  1.1                  embperl/test/cmp/delwrsess.htm
  
  Index: delwrsess.htm
  ===================================================================
  <html>
  <head>
  <title>Tests for Embperl - Delete Session Data</title>
  </head>
  
  
  <body>
  
        udat before:<br>
        <table>
                <tr>
                        <td>a</td><td>1</td>
                </tr>
        </table>
  
        ok (num=1)<p>
  
      $mdat{cnt} = -- <br>
      $udat{cnt} = -- <br>
  
        udat after:<br>
        <table>
                <tr>
                        <td>a</td><td>1</td>
                </tr>
        </table>
  
        ok (num=1)<p>
  
  </body>
  </html>
  
  
  
  
  1.3       +0 -11     embperl/test/html/delsess.htm
  
  Index: delsess.htm
  ===================================================================
  RCS file: /home/cvs/embperl/test/html/delsess.htm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- delsess.htm       2000/09/11 09:53:36     1.2
  +++ delsess.htm       2000/11/09 08:03:16     1.3
  @@ -22,16 +22,5 @@
   
        [- HTML::Embperl::Req::DeleteSession (undef, 1) ; -]
   
  -     udat after:<br>
  -     [- @ks = grep (!/^_/, sort (keys %udat)) ; $num = keys (%udat) - $#ks - 1 ; -]
  -
  -     <table>
  -             <tr>
  -                     <td>[+ $ks[$row] +]</td><td>[+ $udat{$ks[$row] || ''} +]</td>
  -             </tr>
  -     </table>
  -
  -     [+ $num > 0?"ok (num=$num)":"Not a session hash (num=$num)" +]<p>
  -
   </body>
   </html>
  
  
  
  1.1                  embperl/test/html/delwrsess.htm
  
  Index: delwrsess.htm
  ===================================================================
  <html>
  <head>
  <title>Tests for Embperl - Delete Session Data</title>
  </head>
  
  
  <body>
  
        udat before:<br>
        [- @ks = grep (!/^_/, sort (keys %udat)) ; $num = keys (%udat) - $#ks - 1 ; -]
  
        <table>
                <tr>
                        <td>[+ $ks[$row] +]</td><td>[+ $udat{$ks[$row] || ''} +]</td>
                </tr>
        </table>
  
        [+ $num > 0?"ok (num=$num)":"Not a session hash (num=$num)" +]<p>
  
      $mdat{cnt} = -[+ $mdat{cnt} ; +]- <br>
      $udat{cnt} = -[+ $udat{cnt} ; +]- <br>
  
        [- HTML::Embperl::Req::DeleteSession (undef, 1) ; -]
  
        udat after:<br>
        [- @ks = grep (!/^_/, sort (keys %udat)) ; $num = keys (%udat) - $#ks - 1 ; -]
  
        <table>
                <tr>
                        <td>[+ $ks[$row] +]</td><td>[+ $udat{$ks[$row] || ''} +]</td>
                </tr>
        </table>
  
        [+ $num > 0?"ok (num=$num)":"Not a session hash (num=$num)" +]<p>
  
  </body>
  </html>
  
  
  
  1.1                  embperl/test/html/setbadsess.htm
  
  Index: setbadsess.htm
  ===================================================================
  <html>
  <head>
  <title>Tests for Embperl - Set Session Data (with bad cookie)</title>
  </head>
  
  <body>
        [- 
        while (($k, $v) = each (%fdat))
                {
                $udat{$k} = $fdat{$k} ;
                }
        -]
        [+ $udat{_session_id} +]
  </body>
  </html>
  
  
  
  1.1                  embperl/test/html/setunknownsess.htm
  
  Index: setunknownsess.htm
  ===================================================================
  <html>
  <head>
  <title>Tests for Embperl - Set Session Data (unknown cookie)</title>
  </head>
  
  <body>
        [- 
        while (($k, $v) = each (%fdat))
                {
                $udat{$k} = $fdat{$k} ;
                }
        -]
        [+ $udat{_session_id} +]
  </body>
  </html>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to