Page MenuHomePhabricator

Phishing through window.opener with the "Open external links in a new tab or window" gadget.
Closed, ResolvedPublic

Description

@ThePracticalDev pointed out an attack vector allowing phishing with <a> tags with a target="_blank" attribute, but without rel="noopener noreferrer" attribute.

MediaWiki gadget "Open external links in a new tab or window" is adversely affected on Firefox 47.0.1 (haven't checked on 48 yet) and Chrome 52.0.2743.116 m (latest to date).

Reproduce :

  1. Have the "Open external links in a new tab or window" gadget active, as a logged-in user obviously.
  2. Create a link to https://dev.to and preview (or publish, but I'd suggest not on a public wiki :-D )
  3. Click on that link. It opens in a new browser tab
  4. Go back to the tab you're coming from (by closing the new tab or by clicking on the old tab, it doesn't matter)
  5. The old tab has either changed to the resource at https://dev.to/phishing (inoffensive, merely explaining the issue) if you've published, or asked if you want to close it if you've opted for a preview - meaning a window.location tried occurring but was blocked because of the form element : allowing it brings you to the same resource.

You can also reproduce "in a vacuum", thanks to @Platonides : https://servidor.wikimedia.es/go-phishing.html Click on the "go phishing" link in that page.

It can be used as an attack vector if the remote website forces window.opener.location to a seemingly innocuous page (for instance a page that looks like the main page of the wiki you're coming from, or the actual page you're coming from on that wiki if there is only one link to the specific resource that was linked), which resides in fact on a website of the attacker. Any link on that seemingly innocuous page could point to a page that looks identical to a MediaWiki login page, in which the unsuspecting user would gladly fill in their credentials. The attacker only has to store those credentials and be on its merry way.

Granted, the "Open external links in a new tab or window" gadget may not be the most used ; but it is used nonetheless, if anything by me - and I'd really hate to see what effects could arise from that kind of attack used on an account (or accounts) with special permissions.

Proposed patch :
In https://en.wikipedia.org/wiki/MediaWiki:Gadget-exlinks.js (and other WMF wikis at least) and https://www.mediawiki.org/wiki/Snippets/Open_external_links_in_new_window, after this.target = '_blank';, add :

			if ( !this.rel.indexOf( 'noopener' ) < 0 ) {
				this.rel += ' noopener'; // the leading space matters, rel attributes have space-separated tokens
			}
			if ( !this.rel.indexOf( 'noreferrer' ) < 0 ) {
				this.rel += ' noreferrer'; // the leading space matters, rel attributes have space-separated tokens
			}

This should prevent any event relying on that strange yet common browser behaviour.

Thanks :-)

Event Timeline

The proposed fix looks correct to me. I guess this is about finding all copies and modifications of this gadget across all Wikimedia wikis.

(We fixed a similar issue in MediaWiki a couple months ago: T133507. Due to our configuration that did not affect Wikimedia wikis.)

Maybe i should try and get globalinterfaceeditor, so I could just edit all instances

Sadly I was unable to find it on Git.

It seems gadgets such as this one only reside as versionned wiki pages

Sadly I was unable to find it on Git.

It seems gadgets such as this one only reside as versionned wiki pages

Indeed, that is what makes them such a PITA ;)

Oh, well I'll fix that one right now, the non-mw.org one's pending on me figuring out how best to mass edit them all

mwgrep '_blank'

...
(total: 817)

sigh

If we just concentrate first on things doing this.target = '_blank'; we have

arwiki              MediaWiki:FileUploadWizard.js
arwiki              MediaWiki:Gadget-exlinks.js
arwikinews          MediaWiki:Gadget-Popup.js
aswiki              MediaWiki:FileUploadWizard.js
aswiki              MediaWiki:OLD FileUploadWizard.js
bnwiki              MediaWiki:Gadget-exlinks.js
bnwikibooks         MediaWiki:Gadget-exlinks.js
cewiki              MediaWiki:FileUploadWizard.js
cswiki              MediaWiki:Gadget-exlinks.js
enwiki              MediaWiki:FileUploadWizard.js
enwiki              MediaWiki:Gadget-exlinks.js
eswiki              MediaWiki:Gadget-exlinks.js
glwiki              MediaWiki:Gadget-exlinks.js
gomwiki             MediaWiki:Gadget-exlinks.js
hewiki              MediaWiki:Gadget-ExternalLinkNewTab.js
hewikibooks         MediaWiki:Gadget-ExternalLinkNewTab.js
hewikinews          MediaWiki:Gadget-ExternalLinkNewTab.js
huwiki              MediaWiki:Gadget-extlinks.js
idwiki              MediaWiki:FileUploadWizard.js
jawikinews          MediaWiki:Gadget-extlinks.js
jawiktionary        MediaWiki:Gadget-exlinks.js
kawiki              MediaWiki:Gadget-exlinks.js
kkwiki              MediaWiki:Scripts.js/Exlinks.js
kowiki              MediaWiki:Gadget-exlinks.js
kowiktionary        MediaWiki:Gadget-exlinks.js
lvwiki              MediaWiki:FileUploadWizard.js
map_bmswiki         MediaWiki:Gadget-exlinks.js
nlwiki              MediaWiki:Gadget-exlinks.js
orwiki              MediaWiki:FileUploadWizard.js
ptwiki              MediaWiki:Gadget-exlinks.js
ruwiki              MediaWiki:FileUploadWizard.js
shwiki              MediaWiki:FileUploadWizard.js
sqwiki              MediaWiki:Gadget-lidhjetejashtme.js
tawiki              MediaWiki:FileUploadWizard.js
tawikiquote         MediaWiki:FileUploadWizard.js
tawikisource        MediaWiki:FileUploadWizard.js
tewiki              MediaWiki:FileUploadWizard-te.js
tewiki              MediaWiki:FileUploadWizard.js
tewikiquote         MediaWiki:FileUploadWizard.js
trwiki              MediaWiki:FileUploadWizard.js
ukwiki              MediaWiki:FileUploadWizard.js
urwiki              MediaWiki:FileUploadWizard.js
viwiki              MediaWiki:FileUploadWizard.js

(total: 43, shown: 43)

How about any assignment to _blank ? Something along the lines of mwgrep '[^=]=\s*[\'"]_blank'

Well, It would do the trick of finding them at least, sorry to gave you so many to fix ^^°

Currently on a few things already, but I should have more time within a few days : would it help if I suggested actual patches for a bunch of them (if not all of them) ? If so, what would be the preferred way of passing them to you ? And for you to pass me the list of (sigh) 817 occurrences ?

Wait, why is there a ! in:

			if ( !this.rel.indexOf( 'noopener' ) < 0 ) {
				this.rel += ' noopener'; // the leading space matters, rel attributes have space-separated tokens
			}
			if ( !this.rel.indexOf( 'noreferrer' ) < 0 ) {
				this.rel += ' noreferrer'; // the leading space matters, rel attributes have space-separated tokens
			}

Probably because I had a bit of a brain fart when writing it, awfully sorry about that.

This is the correct snippet :

			if ( this.rel.indexOf( 'noopener' ) < 0 ) {
				this.rel += ' noopener'; // the leading space matters, rel attributes have space-separated tokens
			}
			if ( this.rel.indexOf( 'noreferrer' ) < 0 ) {
				this.rel += ' noreferrer'; // the leading space matters, rel attributes have space-separated tokens
			}

JS returns -1 if it can't find a string in another (because reasons), so < 0 is the way to go.

Updated so far:

arwiki              MediaWiki:Gadget-exlinks.js
arwikinews          MediaWiki:Gadget-Popup.js
bnwiki              MediaWiki:Gadget-exlinks.js
bnwikibooks         MediaWiki:Gadget-exlinks.js

I need to get some sleep before work tomorrowtoday, but I copied your fix from those wikis to some of the others:

ptwiki              MediaWiki:Gadget-exlinks.js
nlwiki              MediaWiki:Gadget-exlinks.js
kowiki              MediaWiki:Gadget-exlinks.js
kawiki              MediaWiki:Gadget-exlinks.js
gomwiki             MediaWiki:Gadget-exlinks.js
glwiki              MediaWiki:Gadget-exlinks.js
cswiki              MediaWiki:Gadget-exlinks.js
huwiki              MediaWiki:Gadget-extlinks.js
eswiki              MediaWiki:Gadget-exlinks.js
enwiki              MediaWiki:Gadget-exlinks.js

Still to do:

jawikinews          MediaWiki:Gadget-extlinks.js
jawiktionary        MediaWiki:Gadget-exlinks.js
kowiktionary        MediaWiki:Gadget-exlinks.js
map_bmswiki         MediaWiki:Gadget-exlinks.js
kkwiki              MediaWiki:Scripts.js/Exlinks.js

hewiki              MediaWiki:Gadget-ExternalLinkNewTab.js
hewikibooks         MediaWiki:Gadget-ExternalLinkNewTab.js
hewikinews          MediaWiki:Gadget-ExternalLinkNewTab.js
idwiki              MediaWiki:FileUploadWizard.js

arwiki              MediaWiki:FileUploadWizard.js
aswiki              MediaWiki:FileUploadWizard.js
aswiki              MediaWiki:OLD FileUploadWizard.js
cewiki              MediaWiki:FileUploadWizard.js
enwiki              MediaWiki:FileUploadWizard.js
lvwiki              MediaWiki:FileUploadWizard.js
orwiki              MediaWiki:FileUploadWizard.js
ruwiki              MediaWiki:FileUploadWizard.js
shwiki              MediaWiki:FileUploadWizard.js
tawiki              MediaWiki:FileUploadWizard.js
tawikiquote         MediaWiki:FileUploadWizard.js
tawikisource        MediaWiki:FileUploadWizard.js
tewiki              MediaWiki:FileUploadWizard-te.js
tewiki              MediaWiki:FileUploadWizard.js
tewikiquote         MediaWiki:FileUploadWizard.js
trwiki              MediaWiki:FileUploadWizard.js
ukwiki              MediaWiki:FileUploadWizard.js
urwiki              MediaWiki:FileUploadWizard.js
viwiki              MediaWiki:FileUploadWizard.js

sqwiki              MediaWiki:Gadget-lidhjetejashtme.js

Done a bit more, these are the remaining ones:

idwiki              MediaWiki:FileUploadWizard.js

arwiki              MediaWiki:FileUploadWizard.js
aswiki              MediaWiki:FileUploadWizard.js
aswiki              MediaWiki:OLD FileUploadWizard.js
cewiki              MediaWiki:FileUploadWizard.js
enwiki              MediaWiki:FileUploadWizard.js
lvwiki              MediaWiki:FileUploadWizard.js
orwiki              MediaWiki:FileUploadWizard.js
ruwiki              MediaWiki:FileUploadWizard.js
shwiki              MediaWiki:FileUploadWizard.js
tawiki              MediaWiki:FileUploadWizard.js
tawikiquote         MediaWiki:FileUploadWizard.js
tawikisource        MediaWiki:FileUploadWizard.js
tewiki              MediaWiki:FileUploadWizard-te.js
tewiki              MediaWiki:FileUploadWizard.js
tewikiquote         MediaWiki:FileUploadWizard.js
trwiki              MediaWiki:FileUploadWizard.js
ukwiki              MediaWiki:FileUploadWizard.js
urwiki              MediaWiki:FileUploadWizard.js
viwiki              MediaWiki:FileUploadWizard.js

sqwiki              MediaWiki:Gadget-lidhjetejashtme.js

Several years later: the HTML5 spec has been changed so that <a> tags with target="_blank" behave as if they had rel="noopener" by default, see https://github.com/whatwg/html/issues/4078. This article gives a nice summary: https://mathiasbynens.github.io/rel-noopener/

This change has been implemented in all popular web browsers (Chromium was the last one, releasing the changes in 2020). Given this, I don't think we need to update any remaining scripts like these.

matmarex changed the visibility from "Custom Policy" to "Public (No Login Required)".