Bug #77330 [Nab]: session_id() no longer works inside custom SessionHandlerInterface
| From: | yohgaki@php.net | Date: | Thu, 17 Jan 2019 18:32:00 +0000 |
| Subject: | Bug #77330 [Nab]: session_id() no longer works inside custom SessionHandlerInterface | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-219039@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=77330&edit=1
ID: 77330
Updated by: yohgaki@php.net
Reported by: e6990620 at gmail dot com
Summary: session_id() no longer works inside custom
SessionHandlerInterface
Status: Not a bug
Type: Bug
Package: Session related
Operating System: Linux
PHP Version: 7.3.0
Assigned To: yohgaki
Block user comment: N
Private report: N
New Comment:
BTW, session module API lacks protection that is known as
Seven pernicious kingdoms: a taxonomy of software security errors (7PK) - Encapsulation
https://ieeexplore.ieee.org/document/1556543
or CWE-700
https://cwe.mitre.org/data/definitions/700.html
Users must not change encapsulated session module data structure. i.e. PS globals Since PS globals
must not be changed, session module API should protect these.
Older PHP didn't protect PS globals and let users write bad codes.
Previous Comments:
------------------------------------------------------------------------
[2019-01-17 13:05:24] yohgaki@php.net
You must not ignore errors. Otherwise, it cannot work as it supposed to.
An explanation for the record.
Users must not change session ID for active session.
Note that session_id() changes session module's internal session ID which is saved in PS
globals.
Suppose users are using "files" save handler.
Files save handler does not care session ID stored in PS globals once session is activated because
it only carries file descriptor. session_id() call does not have any effect, since files save
handler simply does not care about changing session ID.
Now suppose one created RDBMS based user save handler.
RDBMS requires different data saving methods, i.e. INSERT for new or UPDATE for existing.
The save handler author would set flag which saving method is required when reading session data
from RDBMS. (There are many ways, but I would do this)
If session_id() is called and changes PS global value for session ID, then writing session would
fail.
No matter how session module try, except forbidding bad usages that cause side effect, it is
impossible to assure portable code that works any save handler.
For me, these kind of _bad_ code is obvious. However, I cannot expect other users, including PHP
core developers, to understand what is good and bad.
Therefore, I forbid any usages that creates side effects.
Users should be able to write portable/workable code for any save handlers as long as they
don't ignore errors.
If there is uncatched case that causes side effect, please report bug. Thank you.
------------------------------------------------------------------------
[2019-01-17 10:46:21] e6990620 at gmail dot com
@yohgaki another version of the test script, with strict_mode enabled with ini_set: https://3v4l.org/pfKge
------------------------------------------------------------------------
[2019-01-17 10:42:55] e6990620 at gmail dot com
The way I see it it's a valid use case, though. A custom session handler that wants to conform
to strict mode needs some way to regenerate the session ID if the one received in the
read($session_id) method is not in the storage area, and that new ID must be passed down by the PHP
engine when it invokes write($session_id, $session_data). Calling session_id() in this context used
to achieve this, but I wasn't aware it was considered an abuse. Are there any other ways to do
the same?
Unrelatedly to this issue, I also believe that session.use_strict_mode should default to true, and
I'm glad to hear you are pushing in this direction.
------------------------------------------------------------------------
[2019-01-17 10:38:31] yohgaki@php.net
ext/session/tests/session_basic2.phpt is not failing, so reporter's 7.3 is not enabling
session.strict_mode. To reporter, please verify.
------------------------------------------------------------------------
[2019-01-17 10:26:10] yohgaki@php.net
Reporter, as documented in UPGRADING, PHP 7.3 has more precise session module state management.
Older session allowed abuses that can harm session and session module. PHP 7.3 disallowed these
harmful/broken usages. i.e. Any changes that can cause "side effect" are disallowed.
This code is trying to change active session state.
https://3v4l.org/6S4XM
Therefore, the code wouldn't work even with ob_start().
Session module was made to work even with harmful/broken usages, and it caused number of bad bugs in
the past.
public function read($session_id)
{
// Simulate a session ID regeneration.
\session_id('newsessionid');
return '';
}
This code is bad code because it is calling session_id() to set "new" id. Setting new ID
in user script for active sessions is bad because it has "side effect" to session module
internal. The "side effect" can break session. Detailed description is omitted.
Anyway, the code is broken. User cannot make any changes that can cause "side effect".
I'll check see if strict_mode is broken or not, since reporter claims that 7.3 allows session
fixation.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=77330
--
Edit this bug report at https://bugs.php.net/bug.php?id=77330&edit=1