Page MenuHomePhabricator

load.php should check read permissions on private wikis (exposes content of wiki pages part of a module)
Closed, ResolvedPublic

Details

Reference
bz58291

Event Timeline

bzimport raised the priority of this task from to Needs Triage.Nov 22 2014, 2:40 AM
bzimport added a project: Security-Core.
bzimport set Reference to bz58291.
bzimport changed Security from none to Software security bug.
Restricted Application changed the visibility from "Public (No Login Required)" to "acl*security (Project)". · View Herald TranscriptNov 22 2014, 2:40 AM
Restricted Application changed the edit policy from "All Users" to "acl*security (Project)". · View Herald Transcript

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:

  1. 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.
  1. 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".

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.

Restricted Application changed the visibility from "acl*security (Project)" to "Custom Policy". · View Herald TranscriptNov 24 2014, 9:28 PM
Restricted Application changed the edit policy from "acl*security (Project)" to "Custom Policy". · View Herald Transcript

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?

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).

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

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).

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:

  1. 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.
  2. 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.
  3. 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.

Krinkle claimed this task.
sbassett edited subscribers, added: Emufarmers; removed: MZMcBride.
sbassett added a subscriber: MZMcBride.
Legoktm changed the visibility from "Custom Policy" to "Public (No Login Required)".Dec 16 2021, 5:39 PM
Legoktm changed the edit policy from "Custom Policy" to "All Users".