Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 1.5.2
-
Fix Version/s: Next Minor Release
-
Component/s: Zend_Session
-
Fix Version Priority:Should Have
Description
this are my options (php.ini):
; Argument passed to save_handler. In the case of files, this is the path ; where data files are stored. Note: Windows users have to change this ; variable in order to use PHP's session functions. ; ; As of PHP 4.0.1, you can define the path as: ; ; session.save_path = "N;/path" ; ; where N is an integer. Instead of storing all the session files in ; /path, what this will do is use subdirectories N-levels deep, and ; store the session data in those directories. This is useful if you ; or your OS have problems with lots of files in one directory, and is ; a more efficient layout for servers that handle lots of sessions. ; ; NOTE 1: PHP will not create this directory structure automatically. ; You can use the script in the ext/session dir for that purpose. ; NOTE 2: See the section on garbage collection below if you choose to ; use subdirectories for session storage ; ; The file storage module creates files using mode 600 by default. ; You can change that by using ; session.save_path = "2;666;/var/sessions/php" ; Define how many bits are stored in each character when converting ; the binary hash data to something readable. ; ; 4 bits: 0-9, a-f ; 5 bits: 0-9, a-v ; 6 bits: 0-9, a-z, A-Z, "-", "," session.hash_bits_per_character = 5
In the path "/var/sessions/php" all directories (0-9 + a-v) and are created
The problem is - If the user set the session id like "?PHPSESSID=xxx" I can't regenerate the session id because session_start() was called before.
try { Zend_Session::start(); } catch (Exception $e) { // echo $e->getMessage(); -> Zend_Session::start() - session_start() [function.session-start]: open(/var/sessions/php/x/x/sess_xxx, O_RDWR) failed: No such file or directory (2) Zend_Session::regenerateId(); // echo session_id(); // -> xxx Zend_Session::setId('test'); -> Exception: The session has already been started. The session id must be set first. }
I think it is usefull to test the current given session id before session_start will call like:
$hashBitsPerChar = ini_get('session.hash_bits_per_character');
if (!$hashBitsPerChar) {
$hashBitsPerChar = 5; // the default value
}
switch($hashBitsPerChar) {
case 4: $pattern = '^[0-9a-f]*$'; break;
case 5: $pattern = '^[0-9a-v]*$'; break;
case 6: $pattern = '^[0-9a-zA-Z-,]*$'; break;
}
if ( !preg_match('#'.$pattern.'#', session_id()) ) {
throw new Zend_Session_Exception('Invalid session id "'.session_id.'"');
}
Issue Links
| This issue is related to: | ||||
| ZF-11420 | Zend_Session doesn't allow you to destory and recreate a session |
|
|
|
Actually, it's much worse...actually a big security issue.
If the session cookie is already set before a user has logged in, Zend_Session will use this value when creating a new session.
The exploit scenario is:
You have a public computer somewhere, and you know that a php application is used by alot of people.
Using Firefox it's pretty easy to delete and set cookies.
You set a PHPSESSID cookie, and note down the value you use. (using it later to do the exploit)
Then, when someone comes and logs in to the php application, your already set cookie will be used.
This only works of course if the browser isn't closed and restarted in the mean time.
The solution is that Zend_Session always should check if the session referred to by the PHPSESSID actually exists, and if not always regenerate the sessionid before creating a new session.
This isn't really a Zend_Session issue alone, since php native sessions are also affected.
But Zend should have a workaround for this I think.