User tests: Successful: Unsuccessful:
Once the session is closed (before write), Joomla\CMS\Session\Storage\JoomlaStorage::close()
creates the base64-decoded serialized session registry within cloning the session registry object ($this->data
):
public function close(): void
{
// Before storing data to the session, we serialize and encode the Registry
$_SESSION['joomla'] = base64_encode(serialize(clone $this->data));
parent::close();
}
Joomla\Registry\Registry
object's magic clone unserializes serialized data:
public function __clone()
{
$this->data = unserialize(serialize($this->data));
}
This unserialize results in magic wakeup of all objects in the session registry.
Joomla\CMS\User
instance in session has the magic wakeup which results in additional load of data.
Basically, we have a chain of User-related magic sleep/wakeup:
User::__sleep()
- on Joomla\Registry\Registry::__clone()
due to serialize()
User::__wakeup()
- on Joomla\Registry\Registry::__clone()
due to unserialize()
User::__sleep()
- on Joomla\CMS\Session\Storage\JoomlaStorage::close()
due to serialize()
This 2nd step is actually an extra wakeup which results in two extra DB queries which don't have any logic because the saved session contains only user ID (see User::__sleep()
) and the session read re-loads the data via User::__wakeup()
.
I don't see any purpose of cloning the session registry before serializing it, any thoughts?
libraries/vendor/joomla/database/src/DatabaseDriver.php
and add after line 639 ($this->executed = $this->statement->execute();
): file_put_contents(
JPATH_SITE.'/tmp/'.microtime(true).'.txt',
$this->sql .
"\r\n" .
print_r($bounded, true) .
"\r\n" .
print_r(debug_backtrace(2), true)
);
:userid
and :muserid
bound params as your user ID:SELECT *
FROM `#__users`
WHERE `id` = :userid
SELECT `g`.`id`,`g`.`title`
FROM `#__usergroups` AS `g`
INNER JOIN `#__user_usergroup_map` AS `m` ON `m`.`group_id` = `g`.`id`
WHERE `m`.`user_id` = :muserid
Joomla executes extra two database queries on each page load for logged user.
No extra queries. Joomla works as before.
No.
Status | New | ⇒ | Pending |
Category | ⇒ | Libraries |
Labels |
Added:
?
|
This pull request has automatically rebased to 4.2-dev.
This pull requests has been automatically converted to the PSR-12 coding standard.
Labels |
Added:
?
|
Labels |
Added:
?
Removed: ? |
Labels |
Added:
?
Removed: ? |
Somebody, please restart drone.
Labels |
Added:
PR-4.3-dev
Removed: ? |
Title |
|
Title |
|
Testing this - I must have done something wrong because I ran into a 500 error and reverting the patch manually did not fix it. After much messing about I now have to re-install my test site. In the logging code above $query does not exist in 5.0.0-beta2-dev. My current error starts with:
Exception:
Failed to start application
at /Users/ceford/Sites/joomla-cms/libraries/src/Factory.php:158
at Joomla\CMS\Factory::getApplication()
(/Users/ceford/Sites/joomla-cms/libraries/src/Session/Storage/JoomlaStorage.php:240)
Test this at your peril!
Labels |
Added:
bug
PR-5.0-dev
Removed: PR-4.3-dev |
Sorry, can't find the issue, merged 5.0-dev into my branch which is X years old.
I have tested this item ✅ successfully on 7632618
I see two fewer queries in the debug bar but four fewer files in my tmp folder. I guess that is OK.
Yes, we have minus two useless SQL queries per each page load.
The files in tmp folder are just for our testing purposes to see the real number of queries because Joomla debug is not able to log all database queries.
@HLeithner We can save two queries.
Needs to be checked from the security implication. This comes from the 3.4.6 security patch when we were trying to protect against malicious session data being used through an old PHP vulnerability (given our minimum version being 7.x I would assume that's been patched out in PHP itself now. Ref: https://www.joomla.org/announcements/release-news/5642-important-security-announcement-pre-release-347.html).
Honestly given how long ago that was I don't remember whether the clone operation was super relevant for that fix or not maybe @SniperSister can remember.
Honestly given how long ago that was I don't remember whether the clone operation was super relevant for that fix or not
It's not, so the patch is fine from a security perspective
Then I merge this, thanks all
Status | Pending | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2023-09-18 11:13:48 |
Closed_By | ⇒ | HLeithner |
@test
patch works
This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/37125.