User:NYKevin/Interface administrators and trusting trust

Interface administrators are users with the ability to edit sitewide CSS and JavaScript. In principle, it is possible for a malicious interface administrator to do almost all things which are not "supposed to" be tied to the interface administrator privilege, as well as some things which are not "supposed to" be possible at all.

This essay will contain some technical information about how such an attack would work, because very few people have these privileges, and they are all highly trusted members of the community. The comparatively negligible risk that one of them will decide to try any of these techniques out is, in my judgment, outweighed by the theoretical significance of these attacks (particularly as applied to subjects like account security, inactivity, and the global sysop and global interface editor rights). I will not be showing specific code samples, because I do not believe this is necessary to explain the risk, and I do not want to facilitate the actions of any script kiddie who might obtain unauthorized access to an interface administrator's account in the future.

While the attacks described below are rather frightening, I would also like to stress that this is not "new information." None of these attacks are peculiar to MediaWiki or Wikipedia, nor do they represent security vulnerabilities that ought to (or can) be "fixed." Rather, these attacks are the logical consequence of giving a group of users unlimited control over JavaScript. Anyone familiar with offensive security, web technologies, and basic facts about Wikipedia gadgets and user scripts should be able to rattle off a similar or identical list of attacks within minutes (and they might well do better than I did). Accordingly, I do not consider this a report of any kind of vulnerability, and have not placed it under an embargo. I have not filed a Phabricator ticket or requested a CVE, and I do not encourage anyone else to do either of those things. The developers are aware of this - that is why we only have 9 local interface administrators, why they're required to use 2FA on their accounts, and why the interface administrator group even exists in the first place (the right was split out in MediaWiki 1.32, ca. April 2018, specifically because of attacks like those discussed below ).

It should go without saying, but nothing in this essay is meant to suggest that anyone who holds this right is likely to take any of these actions. If you are an interface administrator, please interpret this essay as a friendly reminder that your account is very powerful, and you should take account security seriously. For everyone else, think of this as a thought experiment describing what might happen, if an interface administrator's account were compromised.

Background
The ability to edit sitewide JavaScript probably sounds innocuous to some readers. To properly understand the threat, we need to consider the scope in which sitewide JavaScript executes. Specifically, sitewide JavaScript has all of the same powers and privileges as any gadget or user script, but it does not need to be enabled or imported to work. It just runs, automatically, on every page load, for every user who has not disabled JavaScript altogether (or otherwise blocked it). As far as Wikipedia is concerned, the sitewide JavaScript is you - in the sense that the sitewide JavaScript can do everything that you, the human sitting in front of your computer, can do. This creates many opportunities for mischief of various kinds.

Stage 1: Impersonation
The most obvious thing to do is to impersonate whichever user happens to be executing the malicious JavaScript. For the purposes of this discussion, a user is "impersonated" if the attacker is able to cause that user's account to perform an action that would generate either a history event (i.e. an edit) or a log entry, without the user approving (or, possibly, even knowing about) that action. By itself, this is already enough to wreak substantial amounts of havoc: The attacker can make other users commit acts of vandalism, start a fight on ANI, or even suppress inconvenient edits and log entries.

This is actually much less difficult than it sounds. All the attacker really has to do is copy the source code of e.g. Twinkle, rip out the user interface, and replace it with code that decides what the attacker wants the victim's account to do (via a command and control server or by other means). Then, the next time the victim loads any page, their account will silently do whatever the attacker wants it to do. If Twinkle lacks code to do that, then the attacker can just use another tool instead, or write their own. All significant on-wiki actions can be done via JavaScript, given enough effort.

Stage 2: Concealment
The obvious problem with stage 1 is that it generates an edit in the history of MediaWiki:Common.js... or does it? While an attacker could edit Common.js to perform these attacks, this is rather obvious and would be spotted by another interface administrator pretty quickly, if they ever look at that file. On the other hand, it could be obfuscated by editing something like MediaWiki:Group-user.js, which is much less commonly edited, but just as dangerous.

Of course, eventually, someone is going to notice that the wiki is under attack, and try to identify the attacker in order to revoke their privileges. But the attacker has control over the site's JavaScript, so they can hide their own edits (or the edits and log actions of others, for that matter), replace the apparent content of the interface page with the innocuous previous version, and even reprogram the edit interface to re-insert the malicious code when saving changes. A user with JavaScript disabled would be able to "see through" this trickery, but in order to do that, they would first need to figure out that someone is using JavaScript to pull off the attack, or they would need to routinely disable JavaScript and figure it out "by accident." The fact that the attacker has access to blocking, suppression, etc. would make it much more difficult for such a user to raise the alarm, even after they figure it out.

Stage 3: Persistence
The attacker doesn't have control over the entire universe. They can't stop people from talking to each other over IRC or by other off-wiki means. Sooner or later, the community is going to notice discrepancies between what they do on-wiki, and what the wiki's history and logs appear to reflect. Given enough time, we can unravel the whole plot, take the attacker's privileges away, and undo at least a large portion of the damage caused (but probably not all of it, because impersonation leaves log entries identical to non-impersonated actions, so you would have no way of telling what was an impersonation and what was a "real" action, other than by analysis of the malicious and probably obfuscated code).

Or at least, that's what we (the community) would like to happen. Unfortunately, things become much more complicated, because Special:Mypage/common.js exists. This page is normally used to enable and configure user scripts, which are like gadgets, but (in most cases) not polished and/or popular enough to turn into "real" gadgets (there's only so much you can reasonably stuff into Special:Preferences before it gets impossible to navigate). However, you can put arbitrary JavaScript code on that page, and it will run on every page load when you are logged in. Since the attacker can force you to take actions without being aware of it, they can install malicious JavaScript on your personal common.js page, and continue to manipulate your account even after the attack has been removed from the sitewide JavaScript. There's nothing stopping an attacker from doing this to literally everyone who has ever been impersonated. Or, if that's too obvious, they could do it to a very small selection of high-privilege accounts, and hope that the community does not notice.

In an ideal world, the community would be aware of this threat, and systematically audit all edits to common.js and vector.js, for all users, during the affected period. Realistically, that's a lot of auditing, especially considering this attack might have been ongoing for a very long time, so the more plausible outcome is an adminbot that reverts all changes to those pages during the period of the attack, and then leaves a talk page message informing the user that they should redo the change if they want to keep it. Since the overwhelming majority of fully automated bots do not execute JavaScript at all, such an adminbot would be immune to any chicanery.

There is one other possible attack that might become relevant at this stage: Booby trap the login page to steal credentials. For users without 2FA, those credentials could later be used to manually take over their accounts, even after the attacker's privileges have been revoked. Hopefully, the community would also notice this, and alert the WMF to force a password reset on all users.

Overall, persistence seems to be a harder problem than impersonation or concealment. An attacker would need to be very creative to continue the attack after the community is fully engaged with stopping it. On the other hand, some diligence would be required on the part of either the community or the WMF to identify and shut down every possible avenue of persistence. It would be all too easy to miss something in the mad rush to stop the primary attack.