Description
Details
- Reference
- bz58291
Related Objects
- Mentioned In
- T297416: Restrict access to most actions on $wgWhitelistRead pages on private wikis
T200878: Users should be warned againts putting arbitrary code to personal scripts
T180817: Review TemplateStyles patches related to previewing site CSS changes - Mentioned Here
- T186390: Javascript preview feature broken when live previews are enabled
Event Timeline
Without having yet dived into this, I think "bits.wikimedia.org/wiki/load.php can reveal content of MediaWiki:Common.js and friends on private wikis" is a bit overly specific. It's probably more along the lines of...
ResourceLoader's load.php doesn't check if the user has "read" permission
... or something like that.
This may or may not be a valid bug. It is certainly a good thing to be aware of and to think about, but it isn't obviously a bug or a leak.
On private wikis, certain pages are accessible. Such as:
- Reading the Main Page (action=view)
- Viewing history of the Main Page (action=history), and with that certain user names, timestamps and difference views.
- Using Special:UserLogin
- Limited api.php interaction (mostly the above, but the API equivalents).
Loading of the site module (local wiki modification that affect all page for all users in all skins, both logged-in and logged-out) has always been enabled on private wikis, even for the Main Page. This is mostly for 2 reasons:
- Before ResourceLoader, these modifications were loaded as part of the title=-&js hack, and that one was also enabled for private wikis, so we just kept that as-is when ResourceLoader was developed.
- I did consider at some point whether this is by design, and though I don't recall a wider discussion, at the time it seemed sensible because you might want some interaction on the main page (and in case of CSS, it may be intentional that it applies to the Main Page, e.g. mediawiki.org and en.wikipedia.org have various CSS rules in Common.css that are required for the Main Page).
Now, I'm fine with limiting this, it just means that private wikis can't use js/css on their main page (at least not for logged-out users).
But at the moment, the site module has always been public, and is part of the subset that (should be documented if not already) must be kept clean of private data.
(In reply to comment #1)
Without having yet dived into this, I think "bits.wikimedia.org/wiki/load.php
can reveal content of MediaWiki:Common.js and friends on private wikis" is a
bit overly specific. It's probably more along the lines of...ResourceLoader's load.php doesn't check if the user has "read" permission
... or something like that.
It can't check that in the production setup, because bits.wm.o is a cookieless domain (deliberately).
What I think is the first question we should ask: in pre-ResourceLoader MW versions (1.16 and before), did MediaWiki:Common.js et al "work"?
(In reply to comment #3)
What I think is the first question we should ask: in pre-ResourceLoader MW
versions (1.16 and before), did MediaWiki:Common.js et al "work"?
Krinkle's comment suggests the answer to this is "yes".
Generalizing summary since it's not just the site module: https://bits.wikimedia.org/otrs-wiki.wikimedia.org/load.php?modules=ext.gadget.Yellow
Adjusting scope slightly again (sorry), it specifically exposes content of any wiki pages that are currently specified as being part of a ResourceLoaderWikiModule (which is a known set of pages, controlled by sysops or the software only).
(In reply to comment #2)
On private wikis, certain pages are accessible. Such as:
- Reading the Main Page (action=view)
Only if it's whitelisted in $wgWhitelistRead.
- Viewing history of the Main Page (action=history), and with that certain
user
names, timestamps and difference views.
That's bug 32716. :-)
(In reply to comment #4)
(In reply to comment #3)
What I think is the first question we should ask: in pre-ResourceLoader MW
versions (1.16 and before), did MediaWiki:Common.js et al "work"?Krinkle's comment suggests the answer to this is "yes".
Only if "-" was whitelisted in $wgWhitelistRead.
When a user is editing a page, are we able to work out whether it can be included in RL module output and send a warning?
Alternatively, if we do implement read right checks, perhaps can we provide a public.js equivalent to the normal JS/CSS messages which will show on wgWhitelistRead pages, and just stick a huge warning sign on that?
Also all user CSS/JS subpages: https://office.wikimedia.org/w/load.php?debug=true&lang=en&modules=user&skin=vector&only=scripts&user=Tgr+%28WMF%29
A warning certainly would be nice.
See also T186391 and T186390 where it would also be beneficial to know when the current page is a ResourceLoader resource.
The startup module can also be used to list gadgets and thus scan for T186392-style vulnerabilities:
https://office.wikimedia.org/w/load.php?debug=true&lang=en&modules=startup&only=scripts&skin=vector
If we want to make load.php private but still provide JS for anonymous users on the main page, ResourceLoader could embed some kind of authentication token into script URLs on whitelisted pages. (Would not work for dynamically loaded modules, though.)
I don't think the added cost and complexity of tracking state of private vs public is worth it here. I'd much rather limit our solution in a way that allows load.php to remain stateless.
I propose one of the following:
- Enforce "public" audience in WikiModule's call to Revision::getContent. Thus for private wikis, only pages in wgWhitelistRead may be in a module. This would be a major change as the site admin would be required to put all Common.js,Common.css,Vector.css,Vector.js in wgWhitelistRead. Without it, they simply could not be used in a WikiModule (regardless of logged-in state). This means they are hidden by default (for new private wikis and on upgrade) and can be opted-in to by system administrators. The same applies to gadgets, they would only work if their page names are added to wgWhitelistRead by a sysadmin.
- Document them as always public. This is the status quo. This means interface admins are given the responsibility to know they are implicitly making pages public by including them in the site module or in a gadget.
- Make it configurable. We could disable "WikiModule" by default on private wikis (if [*][read] == false), and require a site admin to flip a toggle that if enabled, implicitly bypasses wgWhitelistRead for WikiModule the same way it does already today. This variable, e.g. wgWhitelistSitewideCssJsPages, explicitly transfers the trust to sysops and interface admins (effectively as status quo).
I took a look at the WikiModule source just now and noticed that we already have a configuration option similar to what "wgWhitelistSitewideCssJsPages" would be. It is called "wgUseSiteJs" (and wgUseSiteCSS). These control the allowance of sidewide CSS and JS being exposed to users (including logged-out users on private wikis). So that basically turns option 3 also into a documention-only task, to explain that these can be used to control the same for private wikis.
Using a sitewide secret in load.php URLs would still leave it stateless. I agree showing a warning on affected pages would be an acceptable solution, but I'm not sure that's less complexity.
I've documented this known limitation in the "Restricting page views" manual on mediawiki.org, and recommend that private wikis:
- if they entrust their users with this feature, to consider adding an Editnotice to the User and MediaWiki namespaces to remind their users,
- and/or to revoke edituserjs and thus only allow site-wide scripts
- and/or to restrict edituserjs to interface-admins (or another group) which would require an explicit "Do you understand what this means" check before allowing use of personal scripts,
- or turn off $wgUseSiteJs.
I'm closing this for now, but based on what people want for officewiki and other private wikis, some part of it could be made simpler with a built-in feature of sorts to faccilitate that choice.