Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent auto clicked link XSS attack using CSP

Whilst using CSP for a slightly different purpose (sandboxing) I realized that a very simple auto clicked link seems to bypass even relatively strict CSP. What I am describing is the following:

Content security policy:

default-src 'none'; script-src 'unsafe-inline';

And the body:

<a href="http://www.google.com">test</a>
<script>
  document.querySelector("a").click();
</script>

Obviously in a real attack you would include the cookie information into the href field first and probably wrap this in a hidden self-embedding iframe or make the domain redirect you back to where you came from (potentially with additional url parameters thus creating a sort of XMLHttpRequest bypassing connect-src), but this basic example does show the problem.

Is there any way to prevent this with CSP (which still does allow the execution of Javascript)?


Similar attacks

The same thing can obviously be done with some other navigation methods as well. The reason why I was asking specifically about this method actually has more to with my secondary goals than XSS exploits. Either way, open to any and all real solutions.

Irrelevant side explanation

Because of all the confusion how this could still be applicable even without script-src: 'unsafe-inline'. Imagine the following file named api.ext

print URLParameters.method
[...]

This file could then be called like api.ext?method=<script src='api.ext?method=alert("test")//'></script><!-- (except you would need additional URL encoding and stuff, this is just to get the point across). Finding exploits like this is hard and they are quite rare, but things like connect-src seem to exist to prevent leakage of information even in those cases.

like image 830
David Mulder Avatar asked Apr 20 '15 15:04

David Mulder


Video Answer


1 Answers

This is unlikely going to be a satisfying approach - and obviously it isn't based on CSP - but it might be your only option if you really have to prevent such attacks. Before using anything like this, make sure that there is really no way to disable inline scripts (which should cover most attacks). Moreover, you should send your feedback to the [email protected] mailing list with a [CSP2] subject.

Here my (incomplete) idea:

function guardMethods(clazz, methodNames, urlGetter, allowFilter, reportViolation) {
    var prototype = clazz.prototype;
    methodNames.forEach(function (methodName) {
        var originalMethod = prototype[methodName];
        if (originalMethod) {
            Object.defineProperty(prototype, methodName, {
                value: function () {
                    var url = urlGetter.apply(this, arguments) || '';
                    if (allowFilter(url)) {
                        return originalMethod.apply(this, arguments);
                    } else {
                        reportViolation(url);
                    }
                }
            });
        }
    })      
}

function allowFilter(url) {
    // todo: implement
}

function reportViolation(url) {
    console.error('Redirection prevented:', url);
}

guardMethods(HTMLAnchorElement, ['click', 'dispatchEvent', 'fireEvent'], function () {return this.href}, allowFilter, reportViolation);

You would have to implement similar guards for location, location.href, window.open and other functions/properties/events which allow to redirect to other pages. If you miss just one, then you are still vulnerable. Forms, XHR and most other resources can be covered with CSP itself. As far as I know, the prototype hack does not work in some older browsers.

Once more, I do not recommend to use this. The chance that you make a mistake or that it does not work in some browsers or that a new API will be added which can be leveraged for redirects is just too high.

like image 186
Joel Avatar answered Sep 20 '22 01:09

Joel