@GreenReaper opened this Issue on December 13th 2018

332f42c8798685d1a7df425ebfa42b35937b9b5f (#13540) deprecates the files session hander, setting dbtable as default.

This, or this in combination with some other change, appears to have broken my setup - after upgrading using automatic update from 3.8.0b2, I received continuous 'form security failed' errors when attempting to login with the superuser (the only user, other than anonymous), after submitting to apply database changes (having also run into #13836).

I was only able to login correctly after changing to the file save handler by setting in config.ini.php:

[General]
session_save_handler =

Looking at the table piwik_session there are seemingly valid Base64 serialized strings decoding as e.g.:

a:2:{s:11:"Login.login";a:1:{s:5:"nonce";s:32:"1d94bbb57080ef82062935becf00da7c";}s:4:"__ZF";a:1:{s:11:"Login.login";a:1:{s:4:"ENVT";a:1:{s:5:"nonce";i:1544720442;}}}}

I'm guessing this is the partially-logged-in-session as the ID matches the cookie.

But there are also strange, seemingly corrupted entries that don't even have the "data?" at the front of the data column and presumably aren't going to decode right either, like this:

| id | modified | lifetime | data
| ISbcHaC6nB1ACClXZ059KUsqkN | 1544725496 | 1209600 | datYjowOw==

I also saw errors like this pop up in the debug log:

WARNING Piwik\ErrorHandler[2018-12-13 19:09:25 UTC] [b9532] /[censored]/piwik/libs/Zend/Session.php(495): Notice - unserialize(): Error at offset 43 of 47 bytes - Matomo 3.8.0-b4
...
WARNING Piwik\ErrorHandler[2018-12-13 19:32:30 UTC] [bbf15] /[censored]/piwik/libs/Zend/Session.php(495): Notice - unserialize(): Error at offset 1195 of 1199 bytes - Matomo 3.8.0-b4

I think #13823 was intended to fix this, but maybe it did not work, or caused more problems than it solved.

In case it matters

  • I'm using nginx 1.15.7, accessing /piwik/index.php, the site tracked being at / (but for some reason it seems to be setting a cookie on the '/' path when logging in, and also on '/piwik' once it gets in).
  • The server is using PHP 7.3.0; session.save_handler = files, and session.serialize_handler = igbinary.
  • The OS is Debian stretch, but I am not using the Debian package, just a subfolder on the app root.
@GreenReaper commented on December 13th 2018

Incidentally, if you have database sessions enabled and intentionally corrupt the data field by removing the data? at the front, it suggests that files are the problem and recommends enabling DB sessions:

Error: Unable to start session. Please check that the web server has enough permission to write to these files/directories...

@tsteur commented on December 13th 2018 Member

Incidentally, if you have database sessions enabled and intentionally corrupt the data field by removing the data? at the front, it suggests that files are the problem and recommends enabling DB sessions:

Error: Unable to start session. Please check that the web server has enough permission to write to these files/directories...

that might be just some old comment. Needs to be updated / removed. Created a PR: https://github.com/matomo-org/matomo/pull/13857

as for the other sessions I'm not sure this is related to the DB handler being changed as it seems to work in general when the DB handler is used. not sure if @diosmosis has any idea?

@diosmosis commented on December 14th 2018 Member

@tsteur only thing I can think of is 'files' is may be used somewhere else in the code even after https://github.com/matomo-org/matomo/blob/3.x-dev/core/Session.php#L97. Maybe that causes a problem

@GreenReaper commented on December 14th 2018

Could it relate to use of igbinary as session.serialize_handler in PHP's global configuration? (Changing this globally is something I can't test in production, though I could if it's possible to modify just piwik sessions.)

If there's special handling on your end (it's a custom save_handler?), it might not be binary-safe, or it might assume a certain format - though I appreciate you base64 stuff before storing it in the data field of piwik_session, which is of type text, and it seems the session created initially is correctly stored.

[As for #13857, that change didn't seem to address the minor secondary issue raised; it still assumes that if there's a session error, you must not be using the database handler, so it should recommend it if installed. It doesn't envisage the possibility that an error was thrown by the already-enabled database session handler.]

@tsteur commented on December 16th 2018 Member

created another PR https://github.com/matomo-org/matomo/pull/13864 for the message.

Looking at the code when you set session_save_handler = in config I think it uses the PHP internal session handler (whatever is configured in PHP, it is usually files by default).

I presume you also get the problem when setting session_save_handler = dbtable? For some reason the DB table session handler doesn't seem to work for you by the sounds. Not sure if it could be related to the serialize handler. It being related to igbinary sounds quite reasonable to me though.

Any chance you could try this patch in production? https://github.com/matomo-org/matomo/pull/13865/files

@GreenReaper commented on December 17th 2018

I tried that and I no longer get a form error - and inside the database, it is now storing the typical JSON format. The data within the session data decodes to (with own censoring):

a:4:{s:4:"__ZF";a:1:{s:11:"Login.login";a:1:{s:4:"ENVT";a:1:{s:5:"nonce";i:1545009462;}}}s:9:"user.name";s:[CENSORED]:"[CENSORED]";s:22:"twofactorauth.verified";i:0;s:12:"session.info";a:2:{s:2:"ts";i:1545008872;s:10:"remembered";b:1;}}

Initially I still couldn't login, because - as before - the login form set the new cookie only on the path '/' even though I was accessing /piwik/index.php. But I already had a '/piwik/' cookie from when I was logged in with 'files', so the Firefox presented the '/piwik/' cookie first in requests, and that was not a valid session in the database, so your code set a new cookie (again on '/') and asked me to login again....

After I manually removed my previous cookie on /piwik/ and reloaded /piwik/index.php it found that I was suddenly already logged in from the previous attempt.

To sum up: the pull request would work if you wished to force database usage (though some may still want files?), but you need to be careful because end-users might get caught in the trap above - especially because they would presumably be switching from file-based sessions that already have cookies set.

Note that the issue does not occur in a clean state but only after you sign out (should have tests?):


Load login page /piwik/index.php with no PIWIK_SESSION cookies:

  • PIWIK_SESSION set on '/'

Login:

  • PIWIK_SESSION set on '/' and subsequently many times on '/piwik/'
    [XHR calls not setting path? They are not HttpOnly and are also not Secure - is this #12841?]

Logout:

  • PIWIK_SESSION on '/' deleted, but '/piwik/' remains

Login:

  • PIWIK_SESSION set on '/' but it is overridden by the one on '/piwik/', which is now not logged in.
    [While the /piwik/ one is not Secure and not HttpOnly, neither of these stop it being valid here.]

Arguably the issue is "really" that path is not consistently set for cookies, either when set or when deleted. So when you log out it deletes the '/' cookie but there is a '/piwik/' one to replace it (since a path is not set and the file accessed is /piwik/index.php?...,) and that one isn't removed or replaced when you try to login - instead, only a '/' cookie is set, which is sent as well, but after the '/piwik/' one.

Another option: make sure you test all PIWIK_SESSION cookies; if one isn't logged in, try the next.
Or if both are needed for different things, and must be active at once, maybe name them differently?


In case it matters (almost certainly not for this), I also ran into a warning:

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /[censored]/piwik/vendor/tedivm/jshrink/src/JShrink/Minifier.php on line 243

This is the 'continue' after // check for some regex that breaks stuff

@diosmosis commented on December 17th 2018 Member

@GreenReaper can you test https://github.com/matomo-org/matomo/pull/13869? I believe it is the cause of cookie path change

@GreenReaper commented on December 17th 2018

Yes, it is. I changed that and flushed the file from the opcache. I still could not login, but once I'd removed the existing '/piwik/' cookie, I was able to login, and no more '/piwik/' cookies were created when accessing the dashboard. Subsequently I could logout, the '/' cookie was removed, and I could login again correctly.

So the clean state seems fixed, but you may have an issue with people who already have '/piwik/' cookies.
Then again, it probably wouldn't be any more of an issue than they already have... I think this might have been an issue for a while, I just never looked into it and just cleared out cookies, and it worked for a while.

@diosmosis commented on December 17th 2018 Member

@GreenReaper Updated the PR again this time to respect the login_cookie_path INI config option, which means in your case I think it'll switch the cookie path back to '/piwik/' (which is better, but apologies for for making you clear the cookies again).

Unfortunately I'm not too sure how to clear the cookies for users that would be affected by this since we'd have to know what the incorrect cookie path is and clear it once for every user. Would you have an idea @tsteur? Can't think of anything that would be simple to implement...

@tsteur commented on December 18th 2018 Member

@diosmosis when the login_cookie_path is set, this might not be an issue anymore? If it otherwise uses the wrong session cookie, I assume the user simply won't be logged in and when logging in, the correct cookie will be set on the correct path? I presume we can't detect if the same session cookie is set in different paths and delete them if needed. Only thing I can think of is that when login_cookie_path != / then to maybe always delete the cookie for / (if that makes sense and is possible)

@diosmosis commented on December 18th 2018 Member

That would work, though seems a bit dirty to do that on every request. I suppose if this is the only reported case of this being an issue, perhaps a real edge case...

@tsteur commented on December 18th 2018 Member

👍 to not do it for now

@GreenReaper commented on December 19th 2018

For what it's worth: I tried the additional change in the PR. I (still) only got '/' cookies (which works in a clean-field environment). That makes sense, since I was not using login_cookie_path. Presumably I wasn't doing any other way of indicating the path it was on (I don't know that I have anything specific in nginx to pass the path through), so previously in some cases the path was set to '/' and in others it was left default. The browser would know, of course, so if the path was not set it added '/piwik/' itself.

Once I set login_cookie_path, all cookies were on '/piwik/' instead. Indeed, this overrode [by being sent first] the previously-set '/' cookie even without removing it. Probably a good thing as login will work despite any such cookies, and it doesn't now send the piwik cookie with requests for the main website on '/'.

This Issue was closed on December 18th 2018
Powered by GitHub Issue Mirror