-
Notifications
You must be signed in to change notification settings - Fork 7.8k
session_create_id() fails with user defined save handler that doesn't have a validateId() method #9583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This regression seems to have occurred in PHP 7.4.5: https://3v4l.org/9HCPE 7.4 is in security fixes only, but the fix should be provided for 8.0 upwards. |
…ler that doesn't have a validateId() method
* PHP-8.0: Fix GH-9583: session_create_id() fails with user defined save handler that doesn't have a validateId() method
* PHP-8.1: Fix GH-9583: session_create_id() fails with user defined save handler that doesn't have a validateId() method
* PHP-8.2: Fix GH-9583: session_create_id() fails with user defined save handler that doesn't have a validateId() method
@Girgias Won't your solution of changing the default value to FAILURE just cause the Lines 420 to 426 in 1084715
I tried returning Since |
Can you provide a test case for what you think might now fail? As all tests currently pass. |
When
Desired behavior: Same ID each time, since we are restarting the same session. |
The issue is that PS(mod)->s_validate_sid is always defined for user modules, thus we need to check that the actual callable is set Add another regression test to ensure current working behaviour is not broken (which was by the previous incorrect fix)
The issue is that PS(mod)->s_validate_sid is always defined for user modules, thus we need to check that the actual callable is set Add another regression test to ensure current working behaviour is not broken (which was by the previous incorrect fix)
Description
The following code:
Resulted in this output:
But I expected this output instead:
Here is a summary of the behavior of the above code across various versions, where I tested commenting out the
validateId()
, having it always returnfalse
, and have it always returntrue
:validateId()
validateId()
returns falsevalidateId()
returns trueThe varying behavior over time is believed to be due to two other bug fixes: Fix #79091 and Fix #79413
(The older versions above are listed because they represent the progression of behavior as those fixes were applied. I know most are out of support.)
Those bug fixes created line 2325 below and changed
FAILURE
toSUCCESS
on line 2323, respectively. (No problem with those bug fixes, them being fixed simply revealed this additional bug, and are merely provided for context.)php-src/ext/session/session.c
Lines 2315 to 2342 in 1084715
Hypothesis
I don't know for sure what the issue is, as I'm unfamiliar with the language the source code is written in, but here's is the best I can work out from clues:
Line 2319 contains the actual bug, as (I'm guessing here a little) that line is meant to check if the
validateId()
method exists on the save handler. If it does not exist, the code skips the collision check and just creates the new id without error (2335 is true).However, that line doesn't actually do that, as it appears that
validateId()
is always defined and always returnstrue
if the user defined save handler doesn't override it. (In other words, it claims that every ID is already in use.)That may be due to the following code (again, guessing):
php-src/ext/session/session.c
Lines 1085 to 1088 in 1084715
As a result, 2319 is always
false
, so the 2321else
block always executes, and 2323 is alwaystrue
, which always ends withnew_id = NULL
which after 3 loops lands the code at 2340, emitting the warning.This explanation matches the chart of versions above:
7.2.26: With no
new_id = NULL
there was no way to fail7.2.34 added
new_id = NULL
on 2325, which would cause 2323 to evaluate to true ifvalidateId()
returnedfalse
Later versions then fixed 2323 to be true if
validateId()
returnedtrue
, which inverted (relative to 7.2.34) the behavior we see.(I was unable to test other versions as I need to install PHP via
amazon-linux-extras
, which only on 7.2 allowed me to select which patch to install, didn't allow 7.3 at all, nor 8.1. Installing 7.4 and 8.0 got me 7.4.30 and 8.0.20.)Workaround
A user can work around this issue by adding a
validateId($key)
to their user defined save handler. You just need to have it returntrue
if the passed in$key
is already in use, andfalse
otherwise. See documentation.Comments
I would imagine this bug is pretty widespread in general, as most user defined save handlers will not have a
validateId()
method defined (AWS PHP SDK doesn't, which is why I encountered this issue.) However, most code probably doesn't ever callcreate_session_id()
, which means this problem is encountered extremely rarely.(I think I failed at being "brief", so here's a 4 line TLDR. Sorry, I didn't want my many hours of digging to go to waste.)
TLDR
Causes the following error if SessionHandlerTester doesn't have a
validateId()
method:PHP Version
8.0.20
Operating System
No response
The text was updated successfully, but these errors were encountered: