Escaping quotes in Angular with Freemarker Templates - javascript

In a Freemarker template on a page with Angular, I have the following:
...
ng-init="somevariable = ${(model.usercontrolledstring)}"
...
I want to make sure this is hardened against XSS, so I've set up some escaping rules. However, the following value for model.usercontrolledstring causes JavaScript to execute:
abc'+constructor.constructor('alert(1)')()+'abc
The surprising thing is that when the client receives it, it arrives thusly:
ng-init="somevariable = 'abc'+constructor.constructor('alert(1)')()+'abc'"
So it looks like it's being escaped correctly, but Angular is still deciding to run it!
So I guess my questions would be:
What am I not understanding about Angular? (In particular, its decision to run after decoding html entities)
Is there a proper way of configuring a Freemarker Template to prevent this sort of XSS?

I believe you should use somevariable = '${model.usercontrolledstring?jsString}' there.
Also, if that thing goes into a <script> block, certainly you shouldn't apply HTML escaping there. It's not decoded by the browser inside <script>, so you end up with string values that literally contain '. Unless the string meant to contain HTML as opposed to plain text, that's wrong.

Related

Exploit an XSS when injected Javascript code is returned capitalized

I have found an XSS vulnerability in a piece of code, as I'm able to inject Javascript code in it.
I want to generate the simple alert PoC, but I'm not able to do so as the JS code returned by the server is always capitalized. For example, when I inject the following code:
Text sample <script>alert(document.cookie)</script>
The server respond with the page containing the following:
Text sample <script>ALERT(DOCUMENT.COOKIE)</script>
Which obviously does not print the cookie as JS is case sensitive.
Is there a way to transform the code injected in lowercase before it gets rendered or a similar solution?
Note: Javascript is enabled and if I modify manually the code in the browser console transforming it in lowercase, I'm getting the cookie printed.
No, you do not have control over the transformation and you cannot somehow change it back to lowercase before execution.
However, you can inject JavaScript code which is not affected by the capitalisation of the characters. See jsfuck, which doesn't need alphanumeric source characters at all, and use a similar approach (you can actually use digits and some characters).

Security concerns with Mustache html templating

I have a usecase where the contents of the mustache HTML template could potentially come from the application/end-user (i.e. The content of the script tag in the below code snippet.)
<script id="template" type="x-tmpl-mustache">
Hello {{ name }}!
</script>
As this could potentially lead to execution of malicious code, I'm doing
Allowing only a subset of HTML tags and attributes to be added in
the template (inside the script tag)
Allowing only HTML escaped
variables i.e. only {{name}} is allowed and not {{{name}}}.
Is there anything further that needs to be considered for security of the application?
I think it's not a "moustache" problem if we follow the philosophy "small, sharp tools". Then before mapping an unsecure data (third party JSON) to template you are to validate the data with other tools.
The simplest approach to start with is to replace string fields, contaning unsecure data.
function clearJson(userStringData){
return JSON.parse(userStringData, function(k,v) {
// string values containg something like
// html tags or js block braces will not pass
return String(v).match('[<>{}]') ? 'UNSAFE' : v;
});
}
The field of code injection is too wide to have a short answer on your question. You may apply any approach which is advanced enough for your application: define data formats the application expects from user and then in runtime remove incoming suspicious data not matching these formats.
You should perform user inputs on the server, not "only" on the client. If some "bad code" is going to be executed on the client, it's already too late ;)

Output script tags without jQuery, avoiding execution

I have JS calling remote server through AJAX. The response contains something similar to this
<script>alert(document.getElementById('some_generated_id').innerHTML; ... </script>
User copies the response and uses for own purposes. Now I need to make sure that not a single browser runs the code when I do this:
var response = '<scrip.....';
document.getElementById('output_box').innerHTML = response;
Same should apply to any HTML tags. I know that .text() from jQuery will do exactly what I need:
var response = '<scrip.....';
$('#output_box').text(response);
I am looking for any solutions, including, but not limited to: escaping special characters, however displaying them correctly; adding zero-width space to tags (has to be efficient); outputting in parts. Has to be pure JS.
If you're using a server-side language there is probably a method to escape special characters.
In PHP you could use htmlspecialchars(), it will convert certain characters that have significance in HTML to HTML entities (i.e. & to &).
They will still display correctly and you'll be able to copy and paste the text, but the javascript shouldn't run.
If you need a pure javascript solution for this, someone has answered that here https://stackoverflow.com/a/4835406/15000

HTML Encoded strings recognized by the javascript engine, how's it possible?

Well. This night was a very strange night to me. I am sorry to create a new question after creating two other questions previously, but this is another argument at all. If I get an answer here, I'll get an answer to those questions too so please somebody listen to me and try to understand.
It all began with a simple script JS to be generated through an aspx codebehind file.
On a control, I had to put a JavaScript in this way:
this.MyTxtBox.Attributes["onfocus"] = "windows.alert('Hello World!');";
OK. You might think, where's the problem? The problem is that ASP.NET 4.0 encodes everything, and I say everything in order to avoid XSS to be performed on a site. Well this might not seem a problem but if you look at the rendered page you'll make a jump on the chair like I did:
<textarea id="..." onfocus="windows.alert('Hello World!');"></textarea>
As you can see the html, the final html is a bit odd... JavaScript engine should not accept this situation.
So I started this questions:
ASP.NET quote character encoding causes problems when setting a control's property
Asp.Net encoding configuration
Well I still haven't got any answer YES we could not understand what the hell it is necessary to modify in the .net configuration in order not to let this situation happen.
But now I consider one thing, one important thing: JavaScript engine works!
Even with that odd code that should not be interpreted...
I hope everything was clear until now... The question now comes:
Is this a normal situation for the JavaScript engine?
Does every browser will correctly interpret a JavaScript having quotes replaced with their encoded strings?
If this is true I have to suppose that the .net does not provide a mechanism to avoid encoding just for this reason!
Re:
<textarea id="..." onfocus="windows.alert('Hello World!');"></textarea>
There's nothing odd about that (other than your using windows.alert instead of window.alert). It should work fine (and does; example). The HTML parser parses HTML attribute values, and handles processing entities like '. The JavaScript source code it eventually hands to the JavaScript interpreter will have quotes in it. The browser doesn't hand the literal characters & # 3 9 ; to the JavaScript interpreter.
It's just the same as:
<input type='text' value="This is a 'funny' value too">
The HTML parser processes the entities, and the actual value assigned to the input is This is a "funny" value too.
Incidentally, this is also why this seemingly-innocent HTML is actually wrong and will fail validation (although most browsers will allow it):
<a href='http://www.google.com/search?q=foo&hl=en'>Search for foo</a>
More correctly, that should be:
<a href='http://www.google.com/search?q=foo&hl=en'>Search for foo</a>
<!-- ^^^^^--- difference here -->
...because the HTML parser parses the value, then assigns the parsed result to the href attribute. And of course, an & introduces a character entity and so to literally get an & you must use & everywhere in HTML. (Again, most browsers will let you get away with it if what follows the & doesn't look like an entity. But that can and will bite you.)

cross site scripting in JavaScript

I am trying to resolve a cross site scripting exception in my code.
I'm getting an XSS error at line where I was using JSP expression inside a JS code
ex:
inside a JS function
function ex(){
.....
var loc = '<%= location.getLocDetails()>';
.....
}
Please let me know, if you have any solution/workaround?
Note: location.getLocDetails() returns a String
There's only means of XSS risks if location.getLocDetails() can return user-controlled input. If it for example returns the value straight from the HTTP Accept-Language header without any syntax checking or escaping, then there's indeed means of XSS risks.
You should always escape user-controlled input during display, at least every input which can to a certain degree be controlled by the client, including HTTP request headers and request URL's. It is basically is fairly simple, just use a display tool which escapes HTML entities <, >, " and '.
In case of JSP, easiest way is to use JSTL (just drop jstl-1.2.jar in /WEB-INF/lib if not done yet) <c:out> tag for this. Thus the particular line should be replaced by (assuming that location is already available in page, request, session or application scope):
var loc = '<c:out value="${location.locDetails}" />';
That said, it's right high time to get rid of all scriptlets in your JSP file, it would only make it better :) To learn more about JSTL, read this.

Categories