There are injection scenarios with correct filtering for each HTML context that may have a couple of conditions which allows a successful XSS exploitation. This is done using interesting tricks that will transcend the filter blocking capabilities.
In a regular HTML source code we have 3 contexts for reflection:
1) among tags
2) inside a tag
3) in a script section
For each context, a correct filter have to be applied.
The following code available live here will be used for demonstration of the technique. It applies the following filters (PHP), one for each context:
1) preg_replace(“/\<script|=/i”, “-“, $_REQUEST[‘q’]);
2) preg_replace(“/on\w+\s*=|\>/i”, “-“, $_REQUEST[‘q’]);
3) htmlspecialchars($_REQUEST[‘q’], ENT_QUOTES);
So this page can be exploited? Aside from making use of some weird and old version specific tricks on Microsoft’s Internet Explorer and an attack with the need of high user interaction (both in the end of this post), there are 2 interesting solutions with XML based tags, the ones with built-in support in the HTML5 parser.
We can’t use event handlers. In the previous post, XSS Without Event Handlers, we can see a list of possible candidates to execution. There we can see the <math> tag being used with <brute, as a sign that it is an arbitrary tag (so it can be almost anything).
It can’t be used fully in the 1st context because the “=” is being filtered. But we can split it, because the equal sign is tolerated in the second filter.
But what about the native code between these 2 reflection places?
As we already saw in the post Source-Breaking Injections, we can break the source, making a part of the code “disappear”. Our goal here is not only to invalidate the code between the reflections but also “jump” to bring them together as close as possible.
Using an HTML comment, this is achieved:
And then we land close to our next reflection which is inside an input field of the hidden type. But in the presence of a <math> before it, it becomes a regular tag that can be used to trigger an href.
In order to make it more appealing to a click, the payload for an attack could be:
Interesting enough, it still relies on UI (user interaction) and works only in Mozilla’s Firefox web browser. The next one is much more impressive: it does not need UI and also works on latest Google’s Chrome.
The other XML based tag with built-in support in the HTML5 parser is <svg>. Although much more powerful than <math> regarding XSS exploitation, <svg> can’t be used with the 2nd filter in the same way for a XSS in this scenario.
This happens because the <svg> tag makes the next <script> block be parsed even with chars encoded as HTML entities, hence the breaking out of the native variable value and “concatenation” of the alert function.
What about the native code between <svg> and alert(1)? As the page was carefully crafted to demonstrate this technique, the tags between these 2 are known to be innocuous to this payload construction. We just need to make the first jump, to avoid the <p> tags which would not let this work.
It was pointed out by @httpsonly that it’s possible to XSS in IE version 6 up to 9 using the %00 char to evade the <script regex pattern. There are more bypasses involving these ancient browser versions but it’s worth to note that the filters were designed to prevent XSS in modern browsers. The real unintended bypass came from @asdizzle_ who was able to XSS it with high user interaction in the following way:
” accesskey=x onclick=alert(1) 1=’
It needs pressing of ALT+SHIFT+X keys to trigger the alert and it’s only possible in this scenario because of the technique described here.