Page MenuHomePhabricator

Popups triggers unneccesary cookie for anonymous users
Closed, ResolvedPublic

Description

Every visitors gets an "mwuser-sessionId" cookie when the Popups extension is installed.
As far as I could see this is only used by statsv performance logging however even when

$wgPopupsStatsvSamplingRate

is set to 0 (the default), the cookie is still being created.
This behavior renders varnish caching useless as nothing gets cached due to the served cookies. I can configure varnish to ignore this specific cookie but then it would also ignore the valid cases when pages should not be cached when 'mwuser-sessionid' is served.

Event Timeline

If Varnish is configured to cache-miss on mwuser-sessionId then it is incorrectly configured. This cookie is not in any way related to the server-side of MediaWiki or the concept of MediaWiki backend sessions.

See WMF's Varnish configuration as example:

		if (req.http.Cookie) {
			set req.http.X-Orig-Cookie = req.http.Cookie;
			if (req.http.Cookie ~ "([sS]ession|Token)=") {
				set req.http.Cookie = "Token=1";
			} else {
				unset req.http.Cookie;
			}
		}

The MediaWiki PHP session cookies are named as <dbname>Session with a capital S and ending in the word "Session". If the word "session" is matched more arbitrarily, then it would also match numerous unrelated JavaScript cookies relating to statistics and performance counters.

Having said that, the needless computation of a unique token is still expensive and should of course not happen unless actually neccecary. I am not declining the task as such, merely speaking to the broader picture being reported.

If Varnish is configured to cache-miss on mwuser-sessionId then it is incorrectly configured. This cookie is not in any way related to the server-side of MediaWiki or the concept of MediaWiki backend sessions.

See WMF's Varnish configuration as example:

		if (req.http.Cookie) {
			set req.http.X-Orig-Cookie = req.http.Cookie;
			if (req.http.Cookie ~ "([sS]ession|Token)=") {
				set req.http.Cookie = "Token=1";
			} else {
				unset req.http.Cookie;
			}
		}

The MediaWiki PHP session cookies are named as <dbname>Session with a capital S and ending in the word "Session". If the word "session" is matched more arbitrarily, then it would also match numerous unrelated JavaScript cookies relating to statistics and performance counters.

Varnish does that by default and I was not sure whether I could safely ignore it, but that than does solve main issue i was facing. Thank you.

Jdlrobson subscribed.

The session cookie is not set by page previews. I believe it's set as part of our analytics?

So it's set as a side effect of calling the mw.user.sessionID function here:
https://github.com/wikimedia/mediawiki-extensions-Popups/blob/a35e35e3b397d9e6bac6b4ebe0110441d0a91cca/src/instrumentation/statsv.js#L23 and here https://github.com/wikimedia/mediawiki-extensions-Popups/blob/8f5000f3468f424bc8ad5ef81f35b779943916d9/src/actions.js#L83

The session ID is needed to track several key metrics. I guess it could use session storage instead but that would require a change to mediawiki core.

If the issue here is just around third parties it should be safe to set that to 0 inside page previews when the instrumentation config flags are disabled. Patch welcome.

So it's set as a side effect of calling the mw.user.sessionID function here:
https://github.com/wikimedia/mediawiki-extensions-Popups/blob/a35e35e3b397d9e6bac6b4ebe0110441d0a91cca/src/instrumentation/statsv.js#L23

I guess it could use session storage instead but that would require a change to mediawiki core.

I believe the main computational cost is asking for the session ID to be generated by the Crypto backend. Also, I am not aware of sessionStorage being notably faster than setting a cookie. My experience with the Storage API has thus far been that it is actually slower.

export function isEnabled( user, config, experiments ) {
	const bucketingRate = config.get( 'wgPopupsStatsvSamplingRate', 0 );

	return experiments.weightedBoolean(
		'ext.Popups.statsv',
		bucketingRate,
		user.sessionId()
	);
}

I believe what @Facerafter is saying is that when the rate is 0, it may be worth short-circuiting this code entirely. Either locally here or at a higher level, so as to never compute the Cryptos in the first place nor store them for third parties that don't want or have an active EventLogging + Statsv backend etc.

matmarex subscribed.

I noticed this problem on https://patchdemo.wmflabs.org, which runs many wikis on one domain, and where I have hundreds of these cookies in my browser, one for every test wiki I ever visited. This may not really be a big problem for normal production sites, but it is quite annoying for my weird scenario, as at one point I was unable to log in to that application until I deleted some of the wiki cookies manually (I must have hit some per-domain cookie limit).

It seems like a simple change, I'll send a patch for review.

Change #1053998 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/Popups@master] actions: Remove unused `sessionToken: user.sessionId()`

https://gerrit.wikimedia.org/r/1053998

Change #1053999 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/Popups@master] instrumentation: Avoid `user.sessionId()` if possible, since it sets a cookie

https://gerrit.wikimedia.org/r/1053999

Change #1053998 merged by jenkins-bot:

[mediawiki/extensions/Popups@master] actions: Remove unused `sessionToken: user.sessionId()`

https://gerrit.wikimedia.org/r/1053998

Change #1053999 merged by jenkins-bot:

[mediawiki/extensions/Popups@master] instrumentation: Avoid `user.sessionId()` if possible, since it sets a cookie

https://gerrit.wikimedia.org/r/1053999