Aim ===
To see if it's possible to execute arbitrary client-side JavaScript, using MediaWiki as the delivery system.
Background ==========
To execute arbitrary JavaScript, we mostly need to find a way to get MediaWiki to allow us to open a tag ("<script"), and to close a tag (">"). In particular, we need some form of wiki input text that will produce this as the rendered HTML output.
The MediaWiki parser seems to try to prevent both of these things, by escaping "<" and ">" characters. For example, if you give it wiki input like this: --------------------------------------------------------- <"hello world"> ---------------------------------------------------------
Then you get back this HTML: --------------------------------------------------------- <"hello world"> ---------------------------------------------------------
However, the parser is not perfect. There are some inputs that will give unescaped ">" or "<" back.
The trick is probably to combine these omissions together, in such a way so as to produce a working exploit. I don't have such a thing yet, but I suspect it might be possible.
Unescaped Closing tags ======================
Getting the parser to give unescaped closing tags is much easier than finding unescaped opening tags.
For example, a wiki input of just this: ---------------------------------------------------------
>
---------------------------------------------------------
Will give this HTML output: ---------------------------------------------------------
>
--------------------------------------------------------- (i.e. no escaping).
However, if we try to open one or more tags beforehand, then that changes. So this wiki input: --------------------------------------------------------- <
>
---------------------------------------------------------
Gives this HTML output: --------------------------------------------------------- < >>>>>>> ---------------------------------------------------------
So in other words, we can do this (close a tag and provide some JavaScript to be executed), provided we don't use the "<" character: --------------------------------------------------------- onmouseover="alert(document.cookie)">test --------------------------------------------------------- ... and we will get that literal text back in the HTML.
So to sum up: Any time after we use a "<" character, we lose this privilege of having unescaped ">" characters. To me, this feels like it might perhaps be a mistake, because it allows an attacker an opening that they probably don't need to be given (i.e. it's a free kick).
Unescaped Opening tags ======================
Almost all uses of "<" in the wiki input will result in "<" in the HTML output.
However there are some uses that do not. In particular, I've found that table properties are very weakly restricted, and we can get the Parser to produce unescaped "<" characters with each of the following 3 inputs: --------------------------------------------------------- {| WIDTH=[[image:ftp://~ {| ALIGN='''~~~</math> {| BGCOLOR=<span style="font-weight: bold;"> ---------------------------------------------------------
Which will give this HTML output: --------------------------------------------------------- <table width="[[image:<a" class="external free" title="ftp://~"> <table align="<b><!--LINK"> <table bgcolor="<span"> ---------------------------------------------------------
Some observations / problems here: 1) The unescaped "<" characters are in attribute strings. We need somehow to avoid that, or break out of that, if the browser is to obey them. 2) The type of the tags is limited ("<a>", "<!--" and "<span>" tags in the above examples). 3) The final two examples that use "<" will mean that we cannot close the tag (because, as described above, by using the "<" character we lose the privilege of having close tags).
However we can avoid problem 3) with this, which never uses a "<" character: --------------------------------------------------------- {| WIDTH=[[image:ftp://~ onmouseover="alert(document.cookie)">test ---------------------------------------------------------
Which will give this HTML output: --------------------------------------------------------- <table width="[[image:<a" class="external free" title="ftp://~"> onmouseover="alert(document.cookie)">test ---------------------------------------------------------
... however this still has problems 1) and 2) described above.
Problem 2) may not necessarily be a showstopper (e.g. HTML like: '<a href="#" onmouseover="alert(document.cookie);">Free Porn!</a>' is not as powerful as something that successfully uses "onLoad", but it is predictable that it will work a reasonable percentage of the time).
On the other hand, problem 1) is currently a huge restriction.
Conclusions ===========
* If anyone knows of a way of overcoming problems 1) and 2), or of an alternate method, then please let me know. By combining that information with the information above, it may well be possible to create a working Proof-Of-Concept.
* Why does MediaWiki ever allow unescaped ">" characters? This behaviour seem to increase the chances of a JavaScript security problem.
All the best, Nick.