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)

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

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.

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()

0001-SECURITY-Require-login-to-preview-user-CSS-pages.patch1 KB

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