Chars sanitization and XSS - javascript

I was doing the Google's XSS game (https://xss-game.appspot.com/level4) and I managed to solve the 4th level. I didn't completely undestand how, though.
I don't understand why if I inject the encoding version of a char (let's say %3B) this is translated into the char itself (that is ';') inside the final HTML page. I mean who does this, the browser? Why?
Furthermore, I don't understand where in the code the the injected chars are checked. I made some tests and I've seen that if I try to inject strings like '()';"' whatever comes after the ; is cut out! Where does this happen in the code?
Finally, if I inject a tag like <asd> it is encoded within the <div> (that is <asd>) but it does not in the onload attribute of the <img> tag, where in the code this stuff is performed?

(This answer makes a number of assumptions because I don't have access to Google's client side or server side code (the link goes to an error page because I haven't played the game to reach the level)).
The ((probably) server side) URL parser (which will be part of the server side code) is responsible for converting percent-encoded data in URLs into characters.
; is a key/value separator in form encoding syntax. The URL parser will cut off data at that point.
Responsibility for converting text into HTML is usually given to the template engine, but might be done in some general server side code before data gets to the template (assuming there is a template, the general server side code might just smash strings together).

In order to manage level 4 just enter
')*alert('xss

Related

Safely encoding <script> content in ASP.NET Core (ETAGO Problem)

The project I am working on requires user generated server data to be encoded to JSON and sent down with the HTML document in script tags. At the moment I am doing this with the TagBuilder class using the InnerHtml.AppendHtml(...) method to write the script content.
I have since discovered I have to escape / encode the script content as if the user content has for whatever reason the text "</script>"somewhere, the HTML parser ends the script tag (other HTML probably has various side effects as well).
I read this blog post which describes how to handle the situation in an Node.js environment by using the jsesc library. Does anything similar exist for .NET (ideally Core or Standard)?
I wanted to ask before I roll my own as I'm always weary of doing that for security related code.
Edit
Due to time constraints, for the time being I have injected the JSON into a HTML element as an attribute value, and the ASP.Net Core engine automatically encodes those correctly.
Unfortunately it does increase the size of the HTML document a little more than I would like, as double quotes are encoded as ", but it is what it is.
I'm leaving this question open though in case an answer to my original question comes along.

HTML in JSON that "should" not be there

I have description field in a form.
As suggested here, HTML escaping should not be done in input, so if you put <h1>Description</h1> it is saved like this to database.
The problem is that I have defined a REST API, and the output "could" be HTML.
Should I escape the field when constructing the JSON or should I output HTML in JSON and let the client escape it?.
I feel I should escape the HTML server side, but then this operation would cost processing time. On the other hand, escaping in HTML saves this server time, but people using the API not carefully escaping HTML could end with XSS attacks.
A client may, probably will, be a Javascript client which should process such potential HTML values using the DOM API:
document.getElementById('output').textContent = json.result;
Using this DOM API is perfectly safe and does not require to escape json.result, since it's never interpolated as HTML, but treated as text node by a higher level API. If you send escaped HTML and the client is doing it properly like here, then escaped HTML will be shown on the client; i.e. you're turning your data into garbage.
So, no, never escape values for unrelated contexts. Escape/encode for JSON when putting values into JSON, don't worry about what may or may not happen later.

minimize response from controller action

I am working with asp.net mvc. I note when calling controller actions that return a view via javascript, the html markup returned is not minimized - it includes whitespace etc. Therefore the response size is larger than what it should be.
Is there a way to minimize the response from calling a controller action from javascript?
You might want to look into creating a custom filter to be applied to responses that you want to minify. A technique for this is given in this answer or in this blog post, though you will need to be sure that your implementation of the minification (removing whitespace) does not inadvertantly mess up your code (for example, if you have a javascript content, removing all newline characters can result in all of the following javascript being included in the comment, per this comment).
To this end, it may be worthwhile to use the C# port of Google's htmlcompressor library as a guide for minifying your html.
Of course, you can also just turn on gzip compression on the web server (as Justin points out in the comment below), and get the benefits of compressed output without the headache of implementing (and maintaining) what I detail above.
Note: this may not be worth the effort. A few extra spaces and newline characters in the file that is being sent down the wire will probably not amount to very much space. Even if you save a few KB (which may not even be the case), the increase in performance will most likely not be noticeable. You will however notice that when you try to look at the source of your html in order to debug any issues that you have on the client side, it will be extremely hard to read (spaces and new lines are pretty important for readability).

Preventing / understanding xss with javascript encoding

I'm currently reading up on .net MVC and have just reached the security chapter of the book. I've known about xss, and I never trust any user input without sanitizing it first (usually with html encoding or even something like php's strip_tags). Up until this point I was not familiar with Javascript encoding strings for protection. One of the examples in the book had a user pass in a string like:
\x3cscript\x3e%20alert(\x27test\x27)\x3c/script\x3e
So naturally when I learn something new I want to test it. I created this:
public ActionResult Index()
{
ViewBag.test = "\x3cscript\x3e%20alert(\x27test\x27)\x3c/script\x3e";
return View("index");
}
and this view code that prints out the test string on the page:
#ViewBag.test
However, I cannot get this alert box to show at all. When I view source on the page I get
<script>%20alert('test')</script>
I've tried playing with it a few different ways
Passing the #ViewBag from a query string
putting the viewbag print inside of existing script code (this is how the book had it)
Replacing the %20 with actual spaces
Using jquery to replace html with ViewBag.test:
$('#inject_here').html('#ViewBag.test');
Nothing I try will execute this code (which I guess is a good thing?). Now I know there wouldn't be a portion of this book dedicated to something that didn't work in the first place, so the problem must be on my end. I just don't know what it is. Any one have any ideas?
asp.net MVC tries to take care of this issue for you. It automatically encodes output. You must go out of your way to print out a string without html encoding it.
#Html.Raw(ViewBag.test)
There are places where you will end up doing this in an application. Ideally you would have templates that models are rendered into. But, in some cases you'll have sections of HTML that are dynamic and need to be printed as is. In those cases you'll use the Html.Raw and just need to be aware that you must validate the sanity of the content.

nested quotes in javascript

A bit of a noob question here...
I have a javascript function on a list of table rows
<tr onclick="ClosePopup('{ScenarioID}', '{Name}');" />
However, the {Name} value can sometimes contain the character "'" (single quote). At the moment the error Expected: ')' comes up as a result because it is effectivly ending the javascript function early and destroying the syntax.
What is the best way to prohibit the single quotes in {Name} value from effecting the javascript?
Cheers!
You're committing the first mortal sin of insecure web template programming - not escaping the content of the values being rendered into the template. I can almost guarantee you that if you take that approach, your web app will be vulnerable to XSS (cross site scripting) and any third party will be able to run custom javascript in your page, stealing user data and wreaking havoc as they wish.
Check it out. http://en.wikipedia.org/wiki/Cross-site_scripting
The solution is to escape the content. And to do that properly in the javascript, which is also inside html, is a lot more than just putting escape sequences in front of backslashes.
Any decent templating engine out there should provide you a way to escape content as it's written to the template. Your database values can be left as-is, the important part is escaping it at output time. If your template engine or dynamic web app framework doesn't allow for this, change to one that does. :)
In support of the prior comment please read the following to gain a better understanding of why the security advice is so important.
http://eval.symantec.com/mktginfo/enterprise/white_papers/b-whitepaper_web_based_attacks_03-2009.en-us.pdf
I would think that you could kill just about any code injection by, for example, replacing
"Hello"
with
String.fromCharCode(72,101,108,108,111)
Although the security information provided by everyone is very valuable, it was not so relevant to me in this situation as everything in this instance is clientside, security measures are applied when getting the data and rendering the XML. The page is also protected through windows authentication (adminsitration section only) and the web app framework cannot be changed. The answer i was looking for was really quite simple in the end.
<tr onclick='ClosePopup("{ScenarioID}", "{Name}");' />

Categories

Resources