CSRF in Special:Upload
Closed, ResolvedPublic

Description

  • Original Message --------

Subject: CSRF in image upload
Date: Sun, 18 Mar 2012 15:05:50 +0100
From: Jan Schejbal
To: security@wikimedia.org

Dear MediaWiki development team,
I have discovered a Cross-site request forgery security issue in
MediaWiki. The edit token is not checked for file uploads. This was done
intentionally under the assumption that it is not possible to forge a
file upload using JavaScript. (See includes/specials/SpecialUpload.php,
a comment saying "Skip token check for file uploads as that can't be
faked via JS")

That assumption is wrong. With HTML5 and modern browsers, this is
possible with a few lines of code using FormData and BlobBuilder, and I
think that it probably has been possible for a while with
XMLHttpRequests and custom encoding of the POST body.

Please keep me updated about the steps you take to fix this issue. If
you provide acknowledgements for security bug reports e.g. in the
release notes, please attribute this to "Jan Schejbal / Hatforce.com".

Kind regards,
Jan Schejbal


Version: unspecified
Severity: normal

Details

Blocks
Restricted Task
Reference
bz35317
bzimport added a subscriber: Unknown Object (MLST).
bzimport set Reference to bz35317.

I haven't been able to reproduce this. The documentation on MDN indicates that FormData is only used as a parameter to XMLHttpRequest.send(), but XHR doesn't allow cross-origin requests. XMLHttpRequest.open() fails so it's not possible to send the request.

Can you provide some sample JavaScript code demonstrating this issue?

jan-bugreport wrote:

Demo for successful CSRF image upload on test.wikipedia.org

I have attached a proof of concept. Please make sure you are logged in on test.wikipedia.org with an account that can upload images, then open the attached file. You should be redirected to the uploaded image. Note that this requires a current version Firefox or Chrome.

XHR does not allow to read the response to cross-origin requests, but it does allow to make them.

Attached: image-csrf2.html

Right, my mistake. If I disable the extension I installed in Firefox specifically to block CSRF attacks (RequestPolicy), then it works.

Created attachment 10291
Re-enable CSRF check on upload, disabled in r56793

Suggested commit message:

Revert r56793, which removed the CSRF check for Special:Upload for normal file uploads. Cross-site posting of file uploads without user interaction has been possible since at least as early as Chrome 8 (late 2010) and Firefox 6 (mid 2011).

Commonist has used api.php since version 0.4.0 (April 2010), and the API already requires an edit token, so Commonist 0.4.0+ is not affected by this change.

Suggested announcement mail text:

Jan Schejbal of Hatforce.com discovered a cross-site request forgery (CSRF) vulnerability in Special:Upload. Modern browsers (since at least as early as December 2010) are able to post file uploads without user interaction, violating previous security assumptions within MediaWiki.

Depending on the wiki's configuration, this vulnerability could lead to further compromise, especially on private wikis where the set of allowed file types is broader than on public wikis. Note that CSRF allows compromise of a wiki from an external website even if the wiki is behind a firewall.

attachment bug35317.patch ignored as obsolete

Created attachment 10293
Re-enable CSRF check on upload, disabled in r56793 (v2)

Patch against /trunk/phase3 instead of /trunk/phase3/includes

Attached: bug35317.patch

Created attachment 10294
Patch against 1.18

Patch against 1.18, also applies against 1.17. The difference seems to be just $this->getUser() versus $wgUser.

Attached: bug35317-1.18.patch

Related revision: r114429.

Add Comment