1

I am working on a XSS prevention via Javascript. I am using the following JS-Code for that:

(function () {
/*  
XSS prevention via JavaScript 
*/
var XSSObject = new Object();
XSSObject.lockdown = function (obj, name) {
    if (!String.prototype.startsWith) {
        try { 
            if (Object.defineProperty) {
                Object.defineProperty(obj, name, {
                    configurable: false
                });
            }
        } catch (e) { };
    }
}
XSSObject.proxy = function (obj, name, report_function_name, exec_original) {
    var proxy = obj[name];
    obj[name] = function () {
        if (exec_original) {
            return proxy.apply(this, arguments);
        }
    };
    XSSObject.lockdown(obj, name);
};
XSSObject.proxy(window, 'alert', 'window.alert', false);
XSSObject.proxy(window, 'confirm', 'window.confirm', false);
XSSObject.proxy(window, 'prompt', 'window.prompt', false);
XSSObject.proxy(window, 'unescape', 'unescape', false);
XSSObject.proxy(document, 'write', 'document.write', false);
XSSObject.proxy(String, 'fromCharCode', 'String.fromCharCode', true);
})();

Using that script, it is not possible to execute the functions alert, confirm, prompt, unescape, write and fromCharCode. Is there a way to bypass this prevention? If so, how and why?

  • 5
    What kind of code is this meant to stop? Surely XSS can do quite a bit without those functions. In any case, it's not very robust: var iframe = document.createElement('iframe'); iframe.srcdoc = ''; document.body.appendChild(iframe); iframe.contentWindow.alert.call(window, 'hello'); – Alexander O'Mara Jun 24 '18 at 20:41
  • Sandboxing by blacklisting is kinda failed project since the beginning, JS is just too dynamic in nature. Google Chrome can't block pop-unders, you wouldn't be able to tackle XSS. – Andrew Morozko Jun 24 '18 at 21:07
  • Probably the best thing to do would be to sanitize user input to remove special characters that are required to execute xss, like <>/\' etc. Since JS is dynamic by nature it would be extremely difficult to cover all bases by blacklisting. Also, I haven't attempted this but you might be able to bypass by hex-encoding input, this blog is quite helpful for this specific thing: alihassanpenetrationtester.blogspot.com/2013/01/… – Connor J Jun 25 '18 at 9:10
  • Even if JS was not dynamic, you cannot make blacklisting safe: language will evolve, and upcoming features won't be on your blacklist while being potentially "insecure" in your use case – Xenos Jul 26 '18 at 11:50
1

Yes, there are ways to bypass this security measure. As pointed out in a comment:

var iframe = document.createElement('iframe');
iframe.srcdoc = '';
document.body.appendChild(iframe);
iframe.contentWindow.alert.call(window, 'hello');

The problem is that successfully blacklisting individual functions in such a complex language is an exercise in futility. Trying to prevent real-world attacks by blacklisting is downright quixotic.

0

Some of the functions that you have mentioned, alert, confirm, prompt, are often only used by people who want to prove that there's an XSS by making a PoC.

There's countless other ways to trigger XSS depending on injection point and type of payload, such as using location.href='https://evil.com to load a script from another site, without alerting the victim of any suspicious behavior.

The correct way to minimize XSS as much as possible is to sanitize user input and implement a strict CSP policy. Refer to the OWASP XSS Prevention Cheat Sheet for a non-exhaustible list of measures you can take.

  • I don't get why this got downvoted because. It doesn't indeed shows how to bypass the OP's restrictions, but it shows that you actually don't need to anyway – Xenos Jul 26 '18 at 11:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.