Issues

ZF-11460: Zend_Session::regenerateId doesn't always regenerate session ID

Description

I do the following: (this example is in phpsh)


php> set_include_path('/usr/local/apache2/htdocs/lib/zfdev/trunk/library');
php> require_once 'Zend/Session.php';
php> Zend_Session::start();
php> for ( $i = 0; $i < 10; $i++ ) {
 ... Zend_Session::regenerateId(true);
 ... var_dump(Zend_Session::getId());
 ... }

And the result I get is this:


string(26) "ko1c1649uconma5kal2ugvtir5"
string(26) "0itbujiagvpcvd9nl9nc0gc0r6"
string(26) "0itbujiagvpcvd9nl9nc0gc0r6"
string(26) "6r3cjcaqobqptpf0veacjr4nj6"
string(26) "6r3cjcaqobqptpf0veacjr4nj6"
string(26) "rio861fofl0m8et9on8dtupah6"
string(26) "rio861fofl0m8et9on8dtupah6"
string(26) "jrpiitcceq55ik49d11e8nbre6"
string(26) "jrpiitcceq55ik49d11e8nbre6"
string(26) "d442id0mi40jr56cugc3er9rr3"

Notice the pairs of session IDs? If I re-run the same test using the PHP session_* functions directly, I don't see the same behavior:


php> session_start();
php> for ( $i = 0; $i < 10; $i++ ) {
 ... session_regenerate_id();
 ... var_dump(session_id());
 ... }
string(26) "jhjk6591s2kckuchl73slo22h0"
string(26) "g26ibpifjgauese47tccumrcm5"
string(26) "djui6231b23csoqsfh91bdap02"
string(26) "o2jgluv8dpg2lrrb6o5t4n5b76"
string(26) "f6sat6ftpn47gnjhivooje3v65"
string(26) "19u8srn9mig822t9igkltr2hr6"
string(26) "qvbu42ecj6buuqm23j7nt3jgv4"
string(26) "aeqk6v27j832gtqre19vvseq41"
string(26) "2mdavf0d7dj9964jtrham0fmi0"
string(26) "ocmot7modkickigeaktehedro5"

Comments

Possible fix:


Index: library/Zend/Session.php
===================================================================
--- library/Zend/Session.php    (revision 24131)
+++ library/Zend/Session.php    (working copy)
@@ -307,25 +307,14 @@
             throw new Zend_Session_Exception("You must call " . __CLASS__ . '::' . __FUNCTION__ .
                 "() before any output has been sent to the browser; output started in {$filename}/{$linenum}");
         }
-
-        if (self::$_sessionStarted && self::$_regenerateIdState <= 0) {
+
+        if ( !self::$_sessionStarted ) {
+            self::$_regenerateIdState = -1;
+        } else {
             if (!self::$_unitTestEnabled) {
                 session_regenerate_id(true);
             }
             self::$_regenerateIdState = 1;
-        } else {
-            /**
-             * @todo If we can detect that this requester had no session previously,
-             *       then why regenerate the id before the session has started?
-             *       Feedback wanted for:
-             //
-            if (isset($_COOKIE[session_name()]) || (!use only cookies && isset($_REQUEST[session_name()]))) {
-                self::$_regenerateIdState = 1;
-            } else {
-                self::$_regenerateIdState = -1;
-            }
-            //*/
-            self::$_regenerateIdState = -1;
         }
     }

No unit test yet...will work on that. Need to figure out how to run the Zend_Session test suite first.

The Zend_Session test suite is b0rked, to be honest. What you have in the patch, however, looks similar to the solution I implemented in ZF2; I'm going to simply apply and hope for the best.