Page MenuHomePhabricator

Only allow MediaWiki, Gadget, and User namespace pages to be treated as JS or CSS (no project namespace, etc.)
Closed, ResolvedPublic

Description

This is related to but different from T71445: Implement a proper code-review process for MediaWiki JS/CSS pages on Wikimedia sites. That is about the MW namespace.

There are many pages in project space like https://en.wikipedia.org/wiki/Wikipedia:WikiProject_User_scripts/Scripts/CloseAFD.js . People can import these, but they don't run for every user and are not available in preferences.

These are imported directly, so currently editable by everyone who can edit articles. This problem was recognized long ago, and people have been protecting them manually.

We should prevent those pages from being served as JS (both by using text/plain or similar content type, and with nosniff)

[Old suggestion removed; see history]

Event Timeline

It's difficult for me to figure out whether this task is related to Wikimedia wikis or to MediaWiki generally. Are you proposing adding a "jscurator" user group on Wikimedia wikis? If so, I think you'd need to discuss that at Meta-Wiki for a global user group or on a local Wikimedia wiki for a site-specific user group. My understanding for Wikimedia wikis is that we already have https://meta.wikimedia.org/wiki/Interface_editors, which sounds very similar to the "jscurators" group you're possibly proposing here.

Regarding https://en.wikipedia.org/wiki/Wikipedia:WikiProject_User_scripts/Scripts/CloseAFD.js, maybe it should be a JavaScript gadget instead?

Regarding pages such as User:Example/foo.js, we already special-case these pages in MediaWiki core so that they're automatically protected from regular editing. Administrators and the relevant user (in this case, the user "Example") can edit these pages while others cannot, as I understand it.

It's difficult for me to figure out whether this task is related to Wikimedia wikis or to MediaWiki generally.

Both. In order to set up appropriate groups, I'll believe we'll first need new rights and protection behavior.

Are you proposing adding a "jscurator" user group on Wikimedia wikis?

I'm proposing we solve this problem, and suggesting a first pass at the solution. This is not ready for a patch; I'm starting a discussion.

My understanding for Wikimedia wikis is that we already have https://meta.wikimedia.org/wiki/Interface_editors, which sounds very similar to the "jscurators" group you're possibly proposing here.

No. As I said, "there is a case to make these editable by a wider group than those who edit MediaWiki:Common.js". I.E. the people who can edit MediaWiki:Common.js (including interface editors) is relatively limited, because the MW namespace is critical. The idea is:

a. Not everyone should be able to edit shared JS outside the MW namespace (non-critical shared JS).
b. More people should be able to edit non-critical shared JS than critical shared JS like MediaWiki:Common.js.

Also, it's questionable whether it makes sense for all admins and interface editors to have such broad powers over critical JS. That's being discussed at T71445: Implement a proper code-review process for MediaWiki JS/CSS pages on Wikimedia sites, but this task takes that into account as a base group ("anyone who can edit/merge MediaWiki: namespace JS").

Also, in my proposal jscurators could not edit user JS (unlike interface editors).

Regarding https://en.wikipedia.org/wiki/Wikipedia:WikiProject_User_scripts/Scripts/CloseAFD.js, maybe it should be a JavaScript gadget instead?

That is just a random example to illustrate the general point. There are dozens of scripts in Project namespace, not all of which are high-quality and popular enough to be gadgets.

Regarding pages such as User:Example/foo.js, we already special-case these pages in MediaWiki core so that they're automatically protected from regular editing.

I'm aware of that; that's why that aspect of the proposal is similar.

Whether a shared JS is "critical" or not does not only depend on how many users import it, but mainly on whether a sysop imports it. Any such script could be used to gain access to sysop rights and thus should be protected the same way as MediaWiki:Common.js. I do not think there are that many non-critical scripts to justify a new group. If you don't trust them enough to grant them the editinterface right, they shouldn't be able to edit any shared JS at all.
Instead, I'd like to propose that JS/CSS pages outside MediaWiki: or User: namespace (or other namespaces like Gadget: where they are protected automatically) should be deprecated, and MW finally should stop to send them with a text/javascript MIME type even if requested so, and additionally set the X-Content-Type-Options: nosniff header to make browsers accept that and not to execute such scripts.

Honestly, we should really be rethinking EVERYTHING about user scripts. The current situation is totally unmaintainable. The smallest change to the website can break a dozen or so pieces of 'abandonware' that are used and relied upon by thousands of users...

This stopped scaling a while ago. I think it is time we have a big discussion about what and how we are going to fix this issue, because no matter what the solution is, it's still gonna be 2 years or so before we reach that point.

My point is: As far as I am concerned, we only ever should be delivering JS that is a Gadget or a userscript, and not any other page, so to add more complexity for it, specifically for a Wikipedia namespace, seems long term undesirable to me.

Let's stop delivering JS from Wikipedia namespace instead. It's not even that many scripts and most have been broken for a while already.

The current situation is totally unmaintainable.

+1

Instead, I'd like to propose that JS/CSS pages outside MediaWiki: or User: namespace (or other namespaces like Gadget: where they are protected automatically) should be deprecated, and MW finally should stop to send them with a text/javascript MIME type even if requested so, and additionally set the X-Content-Type-Options: nosniff header to make browsers accept that and not to execute such scripts.

This will cause some temporary disruption, but I support your suggestion.

Whether a shared JS is "critical" or not does not only depend on how many users import it, but mainly on whether a sysop imports it. Any such script could be used to gain access to sysop rights and thus should be protected the same way as MediaWiki:Common.js. I do not think there are that many non-critical scripts to justify a new group. If you don't trust them enough to grant them the editinterface right, they shouldn't be able to edit any shared JS at all.

Giant +1 to this

Instead, I'd like to propose that JS/CSS pages outside MediaWiki: or User: namespace (or other namespaces like Gadget: where they are protected automatically) should be deprecated, and MW finally should stop to send them with a text/javascript MIME type even if requested so, and additionally set the X-Content-Type-Options: nosniff header to make browsers accept that and not to execute such scripts.

Im generally supportive of this in principle.

Mattflaschen-WMF renamed this task from Implement better default protection model for JS files that are not in MediaWiki namespace to Only allow MediaWiki, Gadget, and User namespace pages to be treated as JS (no project namespace, etc.).Dec 23 2017, 2:44 AM
Mattflaschen-WMF updated the task description. (Show Details)

I've edited the description to use @Schnark's proposal.

Mattflaschen-WMF renamed this task from Only allow MediaWiki, Gadget, and User namespace pages to be treated as JS (no project namespace, etc.) to Only allow MediaWiki, Gadget, and User namespace pages to be treated as JS or CSS (no project namespace, etc.).Dec 23 2017, 2:46 AM

I don't think there's need to treat css pages the same way, as you can't inject complex scripts with stylesheets. What do you want to do about them?

On old browsers it is possible to inject scripts into css, but not so much on modern browsers (I think. Havent researched extensively)

The bigger issue with css is potential to either change the site display in a way that's confusing (to aide phising) or to leak data that is privacy sensitive (such as ip addresses). Certainly less of a risk than xss but still not great.

)

Yes, although i still have some follow up to potentially do

Were the CSS restrictions part of that too? With the recent rollout of TemplateStyles, it's now valid to have CSS pages in the Template (and possibly Module?) namespace, so this would have to also be allowed. (I'd assume that this is known, of course, but figure it's also better to explicitly document it in this ticket.)

They don't use the css content model, but a special sanitized-css content model to prevent security flaws. Hence, they shouldn't be affected by this.

Also TemplateStyles CSS is embedded in the page using <style> tags, not fetched directly.

An alternative approach (which maybe requires less effort on the communit side) would be to refuse loading anything that does not have the appropriate content model, and require editsitejs and similar permissions based on the content model (and on not being in userspace).

Is this fixed, given the announcement in https://meta.wikimedia.org/wiki/Tech/News/2018/40?

Note that the announcement is misphrased. Only fully protected pages or pages in the MediaWiki: namespace or user javascript subpages can be loaded as javascript. Compared to the usual JS editing permission requirements, that's still something of an opening.

Is this fixed, given the announcement in https://meta.wikimedia.org/wiki/Tech/News/2018/40?

Note that the announcement is misphrased. Only fully protected pages or pages in the MediaWiki: namespace or user javascript subpages can be loaded as javascript. Compared to the usual JS editing permission requirements, that's still something of an opening.

This shouldn't be hardcoded into MediaWiki core, as other wikis might be using their protection levels differently. Instead, you should be able to specify an array of protection levels which allow a page to be edited, which can include namespace protections as well.

I would like to see this fixed before MW-1.32-release rolls out, as this might break many workflows. Not every Wiki on the world is Wikipedia.

An alternative approach (which maybe requires less effort on the communit side) would be to refuse loading anything that does not have the appropriate content model, and require editsitejs and similar permissions based on the content model (and on not being in userspace).

That would break maintenance of all userspace user scripts, including those people create or want to create for their own personal use. to the point where I think people would break out the torches and pitchforks if we tried that.

That would break maintenance of all userspace user scripts, including those people create or want to create for their own personal use. to the point where I think people would break out the torches and pitchforks if we tried that.

The "similar permission" in that case would be editmyuserjs, of course. The point it should only be possible to load a page as JS if editing it requires one of the JS-related permissions. For user subpages that's already the case (unless someone stores scripts with a nonstandard extension or on the talk page).

The problem is that pages like https://en.wikipedia.org/wiki/Wikipedia:AutoEd/basic.js are currently editable by any administrator, thus circumventing the interface-admin system. That could be solved by requiring a JS content model for the page to be loadable (a sane thing in general, that way you get the right editor, the right formatting, the right redirect behavior etc) and making edit permissions be primarily based on content type instead of namespace/extension.

The "similar permission" in that case would be editmyuserjs, of course. The point it should only be possible to load a page as JS if editing it requires one of the JS-related permissions. For user subpages that's already the case (unless someone stores scripts with a nonstandard extension or on the talk page).

I think T171563#4711600 was unclear.

The current behavior is that editsitejs versus edituserjs versus editmyuserjs is determined based on the content model, namespace, and root page title. When you said "require editsitejs and similar permissions based on the content model (and on not being in userspace)" I read that as you were advocating changing that behavior to determine the right needed solely by the content model, ignoring the namespace (and page title).

It sounds like what you really meant was that serving "loading" something should check the permissions needed to edit it rather than the content model? Or are you advocating that userspace JS have a different content model than other JS, so the permission needed to edit somehow naturally falls out of that (although you still have to decide between edituserjs versus editmyuserjs)?

Currently the condition for applying a JS-based permission check is (in MediaWiki namespace AND (has .js extension OR JS content type)) OR (in User namespace AND has JS content type). The condition for allowing the page to be loaded as a script URL is (in MediaWiki namespace OR in User namespace OR protected) (also if it's in the User namespace the user must exist, but that's a different topic).

My main point is that those two conditions should be aligned. The way I would do it is just look at the content model for both content-type checks and permission checks (and use editmyuserjs if it's in my userspace, edituserjs in another userspace and editsitejs in all other cases (*)), and rely on default content model selection logic for keeping things user-friendly, but that's open to bikeshedding - if we want something closer to the current logic, e.g. (in MediaWiki namespace AND has .js extension ) OR (in User namespace AND has .js extension) OR has JS content type, that's fine. But having pages which are loadable but not protected against editing the same way "normal" Javascript pages are is a problem.

(*) on the code level: change Title::isSiteXXXConfigPage() to check content model + not in userspace, change Title::isUserXXXConfigPage() to check content model + in userspace, add Title::isOwnUserConfigPage() (checks Title::isUserConfigPage() + username match) and use those methods in Title::checkXXXConfigPermissions() and in the RawAction check.

That makes sense, thanks for clarifying. Before we remove the "OR has .js extension" bit we might want to make sure there aren't any other cases where the content could be treated as JS despite the content type.

Another place that should use the same logic is ResourceLoaderWikiModule::invalidateModuleCache which currently uses a mix of Title methods and content models.

chasemp triaged this task as Medium priority.Dec 9 2019, 5:16 PM