symphonycms
symphonycms copied to clipboard
Core creates useles sessions
Current versions of Symphony create a lot of useless session rows in the database when XSRF protection is active and entries are posted in the backend. Session data look like:
sym-|a:1:{s:10:"xsrf-token";a:1:{s:27:"ZR7UtEtKQtgmWeXIkBJDnT1GDAw";i:1;}}
so they don't include a username.
I found that the issue was introduced by e530d0b8630483189ff56c03c1e6561a1e95dc1a ("Move all requires to a single autoload file").
Do you have anymore details I can use to debug this? Nothing is jumping to mind about why that commit would be causing the issue. When you say entries are posted in the backend, do you mean with Events?
No, no events. I am just editing an entry in the Symphony backend (Content > …). I also have no idea why this commit is the issue.
Something is off here. To edit entries in the backend, you must be logged into Symphony. The username
and pass
should be stored in the same session as the XSRF!
Yep, I did it like this:
- delete all rows from the sessions table
- log in to Symphony -> one session is created, as you mentioned above
- edit an entry (just save it multiple times) -> useless sessions have been added
So for some reason new XSRF tokens are generated, which are saved to new sessions.
This is on integration
right? Let me try and replay those steps and I'll what I get locally
I just double-checked, again:
- Check out e530d0b8630483189ff56c03c1e6561a1e95dc1a (or later): broken behaviour.
- Check out one commit earlier (6d239fc7dd234d959b3c61017e264df074179458): everything OK.
I'm using 29000892a2b8d972431a1832d27f82892fd08dc7 and everything is A-OK following your steps. My configuration just has enable_xsrf
set to yes
.
I think the key commit that is missing for your scenario is 1e41aab65c9631688ce78f1830c851db856462b2 which was made to close off #2174
I even tried current integration. :-(
Ah, wait, I disabled some extensions now, and now it works fine. So I will try and find out which extension does it!
Ah, wait, I disabled some extensions now, and now it works fine. So I will try and find out which extension does it!
Let me know!
OK, here we go: Do you remember the problems I had with a special (private) extension when the autoloader was introduced? Because the extension is running background processes, I had to include the autoload logic, and you told me how to do it. So the background worker contains the following code:
// Is there vendor autoloader?
if (@file_exists(DOCROOT . '/vendor/autoload.php')) {
require_once DOCROOT . '/vendor/autoload.php';
} else {
require_once DOCROOT . '/symphony/lib/boot/autoload.php';
}
// Include the boot script:
require_once DOCROOT . '/symphony/lib/boot/bundle.php';
// Begin Symphony proper:
ob_start();
symphony('administration');
ob_end_clean();
This extension causes those useless sessions.
Meanwhile I rolled back Symphony and the extension to see if this has always been a background process issue. The answer is no. With the old code there are no useless session created (and yes, I verified that the background process is indeed working in my test). At that point in time — before autoloading was implemented — the extension used the following code to implement a background worker:
// Include Symphony classes. Rather ugly, but this is the only way.
require_once(DOCROOT . '/symphony/lib/boot/bundle.php');
require_once(DOCROOT . '/symphony/lib/core/class.symphony.php');
require_once(DOCROOT . '/symphony/lib/core/class.administration.php');
$nothing = Administration::instance();
require_once(TOOLKIT . '/class.entrymanager.php');
require_once(TOOLKIT . '/class.sectionmanager.php');
@creativedutchmen, do you have any ideas why autoloading (as in the previous post) creates so many XSRF tokens/sessions? (Or why the old version did not? Or how to prevent this issue?)
I assume that the old version of creating a Symphony object has worked for me because it simply didn't include all the Symphony files, and so (by chance) it didn't attempt to create/verify an XSRF token.
Using autoloader for a background process as mentioned here means that there will be "a complete Symphony" available for the background process, which also means that Symphony will attempt to create an XSRF token (because I configured this for the administration context a.k.a. backend).
@brendo, @creativedutchmen: Is this correct?
If yes, the question is: How could a background process (I also think about the Email Newsletter Manager) start Symphony preventing the generation of an XSRF token (which in turn will create a session)? Maybe we are missing an important feature here?
@michael-e sorry, can't really take a real close look at this moment, I'll have some more free time in two weeks...
However, I do think you are on the right path. In the past only the files that were absolutely needed were included, but we are including a whole lot more now. However, I would think the empty session would not be written to the DB at all, is the function that cleans up the session called at all?
Thanks for the pointers, I will do some more research. The cleanup function, however, will not see the sessions as empty (because they contain XSRF tokens).
Ah yes, of course. If all else fails you can always empty the session, and then call the cleanup function yourself...
Thanks a lot for this idea, it seems to be the simplest solution by far. I do it like this:
// Begin Symphony proper:
ob_start();
symphony('administration');
// If XSRF protection is used, a session will have been generated.
// Drop the useless session:
$_SESSION = array();
cleanup_session_cookies();
ob_end_clean();
@brendo: If you think that this is a "clean enough" solution for background workers, feel free to close this issue.
Can't really help here, just curious...
Shouldn't the token only be created when someone logs into the backend?
The backend process uses the administration "context", this is why it calls symphony('administration')
. Poor Symphony can't know that it's not a human browser. :-)
Ha, you mean only using it after login? Well, no, even the login form uses the XSRF token.
Ha, you mean only using it after login?
Exactly.
Well, no, even the login form uses the XSRF token.
Does this make sense?
Yes, in my understanding of XSRF it makes sense to protect the login form. I may be proven wrong though.
Still, you are right to a certain degree: Creating a Symphony object alone (without any pages being created) wouldn't need to create tokens and/or sessions. But I am afraid that is the way it is implemented. @brendo can probably explain it better than me. :-)
Yes, in my understanding of XSRF it makes sense to protect the login form.
Yes it does!!!
Creating a Symphony object alone (without any pages being created) wouldn't need to create tokens and/or sessions.
I've played with this on my own and the closest thing I could do was to create my own Symphony class implementation. (i.e. not use the Administration class).
But yes, token/session should only be created when required, not always.
Yes, in my understanding of XSRF it makes sense to protect the login form.
Yes it does!!!
Can someone explain this to me, please?
Can someone explain this to me, please?
It does not. It simply does not make sense to protect the login page, as that would imply you know the login details. Which renders the entire attack superflous...
Aha!
It does not. It simply does not make sense to protect the login page, as that would imply you know the login details. Which renders the entire attack superflous...
I can post to the login form outside a browser. It forces the attacker to get a new token for each request, which makes brute force attacks less prone to succeed (because they are more time consuming)
I can post to the login form outside a browser. It forces the attacker to get a new token for each request, which makes brute force attacks less prone to succeed (because they are more time consuming)
Makes sense, I guess. But our current implementation does only generate one token per session, so this only works if the session is destroyed on an unsuccessful login attempt.
Anyway, this scenario has nothing to do with XSRF.
this only works if the session is destroyed on an unsuccessful login attempt.
it should do that IMO.
Anyway, this scenario has nothing to do with XSRF.
I think it does. The whole point of XSRF token is to prevent Cross-site Request Forgery at large. Requesting a login is a request that can be forged.