Last modified: 2011-12-01 00:30:29 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T30798, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 28798 - Interface links can be redirected to hostile domains by cache poisoning on some server setups
Interface links can be redirected to hostile domains by cache poisoning on so...
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
General/Unknown (Other open bugs)
unspecified
All All
: Normal minor (vote)
: ---
Assigned To: Nobody - You can work on this!
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-05-03 17:41 UTC by Aryeh Gregor (not reading bugmail, please e-mail directly)
Modified: 2011-12-01 00:30 UTC (History)
6 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Aryeh Gregor (not reading bugmail, please e-mail directly) 2011-05-03 17:41:30 UTC
Originally sent to security@wikimedia.org on September 18, 2009.  I never got a response, except a bounce message saying tim@wikimedia.org didn't exist.  Nikerabbit was the one who originally pointed it out to me, because it affected translatewiki.net (which has since worked around it).  I haven't tested if it still happens in recent trunk, but I'm not aware of any changes that should make it not happen.

Original report text:

$wgServer is set from the request's domain in most cases.  This is a problem because that domain can be injected into content which is then cached.  For instance, this page:

http://translatewiki.net/w/i.php?title=Special:RecentChanges&feed=rss

At the time I'm reading it, all the RSS links point to "evil2.aryeh.name" instead of translatewiki.net.  To achieve this, I just set evil2.aryeh.name to be a CNAME for translatewiki.net, then browsed to the RSS feed.  Now, hypothetically, anyone viewing that RSS feed on translatewiki.net will get directed to my domain.  I could harvest IP addresses; switch the domain to point to a site containing script intended to infect vulnerable browsers; or lure users into logging in on my domain, stealing their passwords.

The primary mitigation is that most server setups aren't affected.  Shared hosts rely on virtual hosting, so the spoofing won't work.  Only wikis that can be reached by dedicated IP addresses are affected, and only if they don't have some kind of redirect in place for unrecognized domains (like wikia.com does) and don't give an error on unrecognized domains (like Wikimedia sites do).  translatewiki.net is affected, and wikileaks.org also looks vulnerable.  Probably so are a lot of other mid-sized wikis.

I don't see an obvious easy fix to this, but maybe I'm not thinking hard enough.

This was pointed out to me by Nikerabbit, who asked me to file this report.  I mentioned it to TIm privately on IRC, but all he said was "interesting".
Comment 1 Tim Starling 2011-05-05 03:42:39 UTC
We'll work on this for 1.16.6.
Comment 2 Tim Starling 2011-06-07 00:56:42 UTC
One option would be to just drop support for getting $wgServer from the Host header. Instead, only SERVER_NAME or SERVER_ADDR or similar would be used. The installer could use the Host header to set $wgServer in LocalSettings.php, but it wouldn't be used after that.

It wouldn't be useful to do a DNS lookup on the Host header and compare it with the SERVER_ADDR, because the DNS response could be spoofed by the attacker, based on the source address of the query.
Comment 3 Tim Starling 2011-06-07 03:29:26 UTC
It seems that SERVER_NAME already takes priority. The host header is only used if SERVER_NAME is unset, it's been that way since the feature was introduced in r8010. 

On Apache, SERVER_NAME should always be set, judging by ap_add_common_vars(). It also appears to be set unconditionally by Lighttpd's FastCGI module, which is what translatewiki.net seems to be using. RFC 3875 specifies that SERVER_NAME must be set. So this looks like a local configuration issue, due to misuse of the host header in LocalSettings.php, rather than a problem with MediaWiki.
Comment 4 Niklas Laxström 2011-06-07 08:40:08 UTC
It's not a MediaWiki configuration issue. This happens with the default configuration where $wgServer is autodetected. If the rest of your comment is right, then it seems that the server itself sets the SERVER_NAME depending on the user request.
Comment 5 Aryeh Gregor (not reading bugmail, please e-mail directly) 2011-06-07 14:45:54 UTC
That seems to be the case.  Compare the following:

http://www.twcenter.net/~aryeh/tmp/test.php
http://thor.twcenter.net/~aryeh/tmp/test.php
http://mjollnir.twcenter.net/~aryeh/tmp/test.php

It's the same file, consisting of "<?php var_dump($_SERVER['SERVER_NAME']);", served at three different domains.  They output www.twcenter.net, mjollnir.twcenter.net, and thor.twcenter.net respectively.  This is lighttpd's mod_fastcgi.

My server isn't vulnerable to this attack because I have a 301 set up from any unrecognized domain, which triggers before PHP is launched.  That's the obvious workaround, and translatewiki.net should do it -- it might help for SEO too -- but it's not a fix that MediaWiki can rely on.  As noted, I did actually carry out the exploit in practice against translatewiki.net back in September 2009, so it's definitely possible unless something basic has changed since then.
Comment 6 Aryeh Gregor (not reading bugmail, please e-mail directly) 2011-06-07 14:52:07 UTC
As far as doing a DNS lookup on the Host header, I don't think we have to worry about the attacker spoofing the DNS response -- that's nontrivial.  But the attack scenario is that the attacker legitimately controls the domain name given in the Host header, and has pointed its actual A records to your wiki's address, and will later point them to some evil lookalike site that will phish your password or something once the caches are poisoned.  So of course the Host header will resolve to SERVER_ADDR.

Is there any reason we should be generating absolute URLs anywhere to start with if they point to $wgServer?  The exploit doesn't work if the URLs are changed to be relative, and you'd also save bytes in the output.

Also, would there be any substantial harm from just setting $wgServer to a constant string on install, namely whatever SERVER_NAME at install time?  That would also prevent the aesthetic issue of mixing foo.com and www.foo.com URLs or similar, in cases where sites don't have a redirect set up from one to the other.
Comment 7 Tim Starling 2011-06-08 06:37:39 UTC
(In reply to comment #6)
> Is there any reason we should be generating absolute URLs anywhere to start
> with if they point to $wgServer?  The exploit doesn't work if the URLs are
> changed to be relative, and you'd also save bytes in the output.

It's required to use absolute URLs in redirects, and 301 redirects in particular are cacheable. I wouldn't be surprised if it were required in RSS also. 

> Also, would there be any substantial harm from just setting $wgServer to a
> constant string on install, namely whatever SERVER_NAME at install time?  That
> would also prevent the aesthetic issue of mixing foo.com and www.foo.com URLs
> or similar, in cases where sites don't have a redirect set up from one to the
> other.

I don't know about substantial harm, but it would certainly be disruptive and inconvenient, especially in a minor release.
Comment 8 Tim Starling 2011-06-15 04:38:31 UTC
How about this: let's set $wgServer in the installer in 1.18, and remove $wgServer autodetection from DefaultSettings.php a bit later, say in 1.20. Then in the meantime, I'll post an advisory to mediawiki-announce along the lines of:

It has come to our attention that allowing MediaWiki to detect the server name automatically may be insecure. An attacker may set an incorrect Host header, and if the webserver does not properly validate this Host header, MediaWiki may cache the incorrect server name. Then when other users attempt to access the wiki, the incorrect server name may appear in links. If a user follows such a link, privacy loss may result. There is a potential for more severe consequences, depending on the configuration of the wiki.

Thus, we advise all MediaWiki users to set $wgServer in LocalSettings.php, instead of relying on it being set automatically. For example:

$wgServer = 'http://wiki.example.com';

If you set it based on the Host header, make sure you validate it properly, for example:

if ( in_array( $_SERVER['SERVER_NAME'], 
    array( 
        'wiki1.example.com', 
        'wiki2.example.com
    ) ) )
{
    $wgServer = 'http://' . $_SERVER['SERVER_NAME'];
} else {
    die( 'Invalid hostname' );
}

Starting in MediaWiki 1.18, the installer will generate a LocalSettings.php with $wgServer set to a fixed string. In a future release, autodetection of $wgServer will be removed, and any wikis relying on it will stop working.

[end proposed advisory]
Comment 9 Aryeh Gregor (not reading bugmail, please e-mail directly) 2011-06-15 13:56:00 UTC
Why do we need to remove $wgServer autodetection ever?  Set it by default in new LocalSettings.php, so new sites will be secure.  Post an advisory telling old sites that they should set it manually themselves.  And add checks to update.php and maybe a couple of other places that will tell the administrator to set it explicitly if it's being autodetected.  Maybe add the checks to Maintenance.php, so they run every time the admin runs any maintenance script.

We don't need to break existing sites.  The vulnerability doesn't affect shared hosts at all, since those all use domain-based virtual hosting.  The small minority of MediaWikis on dedicated servers or VPSes are only affected if no domain-based virtual hosting is used, which excludes all wiki farms; and if there are no automatic redirects to the canonical domain.  And for sites that are affected, it doesn't have much potential impact.

Any security announcement should start by mentioning all the installations that *aren't* vulnerable, so that the large majority of users know they can ignore it.
Comment 10 Platonides 2011-06-15 16:22:19 UTC
Thanks for adding me, Tim. I see now that we should add $wgServer to LocalSettings. But I also agree with Aryeh that we shouln't remove autodetection support. The whole thing reminds me the r77423 issue.

I'm not as convinced about adding $wgProto to LocalSettings.php. On most sites https won't be availabl, but we could be blocking https: access to the users (at the cost of a small cache pollution) for sites which allow both http & https to the host. $_SERVER['HTTPS'] doesn't look to be spoofable.

http://web.resource.org/rss/1.0/spec doesn't mention whether the URLs must be absolute or not. There probably is some user agent that only accepts them absolute.
Comment 11 Aryeh Gregor (not reading bugmail, please e-mail directly) 2011-06-15 17:42:45 UTC
Who mentioned $wgProto?  I can't see any reason to worry about that.
Comment 12 Tim Starling 2011-06-15 22:09:21 UTC
(In reply to comment #11)
> Who mentioned $wgProto?  I can't see any reason to worry about that.

He's reviewing r90105.
Comment 13 Rob Lanphier 2011-11-17 00:51:11 UTC
Looks like it's been fixed, but probably needs testing.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links