The code below, currently online at United website (which has a bug bounty program at the time of this writing) overrides (hence the name) functions like alert(), prompt() and confirm(), in order to not let them be used by a tester. It’s included as a source of a script tag so it always loads before any injection.
Setting up a test page is straightforward:
Soon, we realize that library has to be used with some server side filtering in order to be effective at least against less skilled testers. With ability to input any XSS vector/payload, it becomes easy to figure out a bypass. But let’s consider that we are able to get the following injection reflected:
It doesn’t work, document.write() is hijacked also. But library is forgetting to hijack its twin function, document.writeln():
With the ability to write to document, we jump to the URL hash, where code is never sent to server and won’t be noticed:
<svg onload=document.writeln(decodeURI(location.hash))>#<img src=1 onerror=alert(1)>
It works. But it would not work in the wild. Why?
When trying to bypass this lib in United website, I tried the same thing without success. That’s because the page is loaded in the same exactly way but with the injected image included:
The library is still present in the page, so it hijacks alert() before it can be executed. Another trick is needed to include in the document without get caught by lib:
By using an iframe we are able to run code without the presence of “js-override.js”, with a brand new document (the iframe’s one) included in our target page.