user1531921
user1531921

Reputation: 1432

Using Mvc Razor string encoding to protect against AngularJS sandbox escapes

I have some odd behavior here that I'm trying to understand.

I'm using MVC 5 with AngularJS version 1.4.5. This version of Angular is vulnerable to some XSS attacks since you can escape the sandbox.

The following string will give a alert with the text "5":

{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(5)//');}}

I have a razor page, Index.cshtml with the following razor code and HTML:

<div ng-app="">

    <div>
        @{
            var breakAngular = "{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(5)//');}}";
        }

        @breakAngular

    </div>
</div>

Now, the razor engine will always encode html on rendering the page, thus "{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(5)//');}}" is translated to a harmless "{{&#39;a&#39;.constructor.prototype.charAt=[].join;$eval(&#39;x=1} } };alert(5)//&#39;);}}"

However, the alert still executes when I load the page.

I would expect the server-side razor engine encoding the string with the attack vector before outputting it would mean that the string is made safe, yet the alert still executes when the page is loaded.

It's like the angular sandbox can somehow access the string and intepret it before the razor angine gets the chance to sanitize the string which makes no sense.

What am I missing here and is there any way to protect against this type of vulnerabilities?

Unfortunately, updating angularJS is not a possibility at this point!

Update

Apparently this works in protecting against the angularjs sandbox escape.

@Html.Raw(Html.Encode(breakAngular))

Upvotes: 0

Views: 228

Answers (1)

Erlend
Erlend

Reputation: 4416

The Angular documentation has traditionally been pretty clear on the dangers of mixing client and server side templating. Razors default encoding is meant to mitigate XSS under certain conditions, but of course cannot fix all kinds, as different client-side templating frameworks introduce different templating mechanisms.

I would not put user provided data inside of an angular templating like this. If you need to provide data from the server, one way to fix this, could be to put it outside of ng-app, and rather use javascript to fetch the values from the DOM.

Upvotes: 1

Related Questions