Page MenuHomePhabricator

XSS via CSS user subpage preview feature
Closed, ResolvedPublic

Description

When previewing Special:Mypage/common.css, we include the contents in an inline <style> tag. We do not properly escape "</style>" thus allowing arbitrary html. This preview mechanism is protected by a CSRF token, so the lack of escaping should not be all that bad (Since people can just do user js anyways), but the preview is allowed for Anon users, who have a predictable token, and thus the CSRF protection is insufficient.

Steps to reproduce:

  • Be logged out
  • Go to Special:MyPage/common.css (On a wiki where anons are allowed to create pages. So say fr.wikipedia.org. On enwiki anons can't create pages so this is harder to pull off)
  • Put the following in the edit box:
/* ]]></style><script>(window.RLQ=window.RLQ||[]).push(function() {alert( "Hello" );</script><style>/*<![CDATA[*/
  • Hit preview. Note that the script is executed.

Furthermore, since this is an anon, the edit token is always '+\'. Thus we can use a CSRF type attack to do this to a user without their cooperation.

  • On some other website, set up a form that that does a POST request to the wiki, with all the same fields as what the above would have done.
  • Javascript is now executed in the context of the wiki

I believe this could further be abused using central auth (however, I haven't tried this part):

  • Lets say user normally uses enwiki only, and is logged in there. User does not normally visit wikiversity
  • Someone does the POST CSRF thing listed above to wikiversity. It should work, since user has not started session on wikiversity yet.
  • However, the central auth Special:CentralAutoLogin/checkLoggedIn script should log the user in by the time the page is fully finished loading. Thus the javascript should be running in the context of the user's credentials after a couple seconds.
  • Thus we can have an XSS of any user

There seems to be three issues at play here:

  • We should not be previewing CSS in the event the user is logged out
  • As the TODO on Html::inlineScript notes, we should be escaping </style> and ]]> inside inline CSS blocks
  • Anons should have real tokens ( T40417 )

Even if the No preview of CSS for logged out users is fixed, this is still very surprising that a user can so easily execute javascript from their css page (I know there are some sort of unsafe things in general css, but most of them are super-old browsers only, or at least require some user interaction). I imagine most admins who test other people's css are not as careful with the css files as they would be with js files, so this could probably be used as part of a phishing attack.

Event Timeline

csteipp subscribed.

Very nice find. This could definitely be abused to spoof the login page, so I'm going to rate it high.

We really need to fix the anonymous token. Maybe next week we can work up a plan for getting that fixed?

In addition to doing this for Html::inlineStyle, it would probably be good to do something similar for Html::inlineScript. However that is both more difficult (Since < is actually used in javascript in contexts where you can't replace it with \x3C), and also probably doesn't matter much, since if you can make arbitrary js, you've already got the keys to the kingdom, and if you can only control a variable value, its < and > are probably properly escaped by Xml::escapeJsString()/Xml::encodeJsVar()

We really need to fix the anonymous token. Maybe next week we can work up a plan for getting that fixed?

I'd definitely love to see that fixed.

Updated patch for escaping <:

dpatrick claimed this task.
dpatrick subscribed.

22:44 dapatrick: Deployed patches for T133147 to wmf.10

@dpatrick:

is still around as of 1.28.0-wmf.14 (in /srv/patches) and doesn't apply cleanly to 1.28.0-wmf.15. Can I assume it's safe to drop the patch?

ok I got the patch to apply. Now I just wonder why this task is closed since the patches are not merged to master.

ok I got the patch to apply. Now I just wonder why this task is closed since the patches are not merged to master.

Generally most security bugs get closed when patch is deployed, not when patch is applied to master (Unless there is some further action required beyond just merging the patch to master)

demon changed the visibility from "Custom Policy" to "Public (No Login Required)".Aug 23 2016, 1:23 AM

Change 306118 merged by jenkins-bot:
SECURITY: Require login to preview user CSS pages

https://gerrit.wikimedia.org/r/306118

Change 306127 had a related patch set uploaded (by Ejegg):
Require login to preview user CSS pages

https://gerrit.wikimedia.org/r/306127

Change 306128 had a related patch set uploaded (by Ejegg):
Escape '<' and ']]>' in inline <style> blocks

https://gerrit.wikimedia.org/r/306128

Change 306109 merged by jenkins-bot:
SECURITY: Require login to preview user CSS pages

https://gerrit.wikimedia.org/r/306109

Change 306119 merged by jenkins-bot:
SECURITY: Escape '<' and ']]>' in inline <style> blocks

https://gerrit.wikimedia.org/r/306119

Change 306127 merged by jenkins-bot:
Require login to preview user CSS pages

https://gerrit.wikimedia.org/r/306127

Change 306128 merged by jenkins-bot:
Escape '<' and ']]>' in inline <style> blocks

https://gerrit.wikimedia.org/r/306128

Change 306110 merged by jenkins-bot:
SECURITY: Escape '<' and ']]>' in inline <style> blocks

https://gerrit.wikimedia.org/r/306110

Change 306090 merged by jenkins-bot:
SECURITY: Require login to preview user CSS pages

https://gerrit.wikimedia.org/r/306090

Change 306091 merged by jenkins-bot:
SECURITY: Escape '<' and ']]>' in inline <style> blocks

https://gerrit.wikimedia.org/r/306091

Change 306099 merged by jenkins-bot:
SECURITY: Require login to preview user CSS pages

https://gerrit.wikimedia.org/r/306099

Change 306100 merged by jenkins-bot:
SECURITY: Escape '<' and ']]>' in inline <style> blocks

https://gerrit.wikimedia.org/r/306100