Escaping characters to avoid XSS in Java - javascript

I need to escape characters to avoid XSS. I am using org.apache.commons.lang.StringEscapeUtils.escapeHtml(String str), which helps in the following way:
Raw input
" onmouseover=alert() src="
After escaping HTML becomes
" onmouseover=alert() src="
However, there are cases in which the reflected input is trapped in single quotes, such as:
test'];}alert();if(true){//
In that particular case, escaping HTML does not have any effect. However, org.apache.commons.lang.StringEscapeUtils also has a method called escapeJavascript(String str), which would convert the input into:
test\'];}alert();if(true){\/\/
The question here is, would you sanitize your input by escaping HTML first and then Javascript? The other would be to replace the single quote character with \' manually.
Any help will be greatly appreciated!

As #gabor-lengyel mentioned I should be able to escape a single quote with an html encoder.
The problem I had is that I was using org.apache.commons.lang.stringescapeutils.escapeHtml and it is not capable of escaping single quotes with the corresponding HTML entity. I am now using org.springframework.web.util.HtmlUtils.htmlEscape, which is capable of dealing with both double and single quotes.
Thank you #gabor-lengyel again for your help!

Related

Escaping several quote levels in vues templates

Going through the Vue online guide, I ran into something that looks like a quote escaping problem. More specifically, I am toying around with the example provided in chapter components->events.
The template in my component looks like
"<div class=\"blog-post\">\
<h3>{{ post.title }}</h3>\
<button #click=\"$emit(\\\"enlarge-text\\\")\" >Enlarge text</button>\
<div v-text=\"post.content\"></div>\
</div>"
And instead of the expected button, I get the string
")" >Enlarge text
I managed to circumvent my issue by replacing the two occurrences of the double escape \\\" by single quotes, but I have the feeling there is something I am missing here. Can you help me to understand what is happening here or provide me pointers towards the relevant doc?
Any explanation is welcome.
As I'm sure you're aware, escaping is used to include characters literally within text that would otherwise be interpreted as having a special meaning. Establishing which characters have special meaning requires us to look at the 'channels' that will be interpreting that text and then select a suitable escaping mechanism for those channels.
In this case the text will be interpreted by 3 channels...
As a JavaScript string literal.
By the Vue template compiler, which has a format very similar to HTML.
Expressions within the template, such as binding expressions, will be treated as JavaScript, potentially including yet more JavaScript string literals.
JavaScript string literals use the \ character to introduce escape sequences. However, the HTML-like syntax used for Vue templates do not. As for HTML they use entities prefixed with &.
So, working backwards, we first need to consider how we escape the expressions within the template. In this case that is $emit("enlarge-text"). As the string "enlarge-text" doesn't contain any special characters we don't need to apply any escaping. Easy so far.
Then we need to escape the template 'HTML'. Now we do run into problems because the #click attribute is delimited with double-quotes and its value contains double-quotes. Obviously we could dodge the issue by using different types of quotes but if we instead hit the problem head-on we'd need to use & entities to escape those quotes. i.e. " for ". That gives us:
<button #click="$emit("enlarge-text")">Enlarge text</button>
I believe this is where the escaping in the question goes wrong as it attempts to use \ escaping to escape the attribute value.
If we were using SFCs then that would be sufficient. But for a template written as a string literal we've still got one more level of escaping to apply, using \. The original quotes around enlarge-text are no longer present so they don't require any further escaping but we still have the quotes around the attribute. That gives us:
"<button #click=\"$emit("enlarge-text")\">Enlarge text</button>"
However, all that said, the usual conventions when specifying string templates are:
Use backticks for the template string itself, giving better multi-line support.
Use double-quotes around attributes.
Use single-quotes for strings within expressions.
Obviously there are cases where that isn't possible, such as if you want to use backticks within an expression, but if you stick to those conventions as much as possible you usually won't need to escape anything. When you do it'll also be a lot simpler to perform the escaping as you aren't using the same delimiters at all three levels.
You could use template literal / template string for this:
let tpl = `<div class="blog-post">
<h3>{{ post.title }}</h3>
<button #click="$emit('enlarge-text')">Enlarge text</button>
<div v-text="post.content"></div>
</div>`;
Not only does it read better, it is way more maintanable than multiple escaped quotes.
You can wrap enlarge-text with single quotes. Like this:
<button #click=\"$emit('enlarge-text')\">Enlarge text</button>

How do you use multiple quotes in javascript?

What do you do when you already have single and double quotes in a URL, but then you need to wrap that URL in quotes?
For example:
<script src="http://(some url text)xpath='//*[#id="node-1075"]/div/div[1]/div/div/p[2]'"></script>
The node ID is wrapped in quotes, if I put the URL alone in the address bar it works, but as soon as it gets wrapped in quotes it doesn't, I can't escape the quotes either or else it will fail, what do I do?
You should be able to replace the double quotes with: %22
And the single quotes with: %27
So your URL would be:
"http://(some url text)xpath=%27//*[#id=%22node-1075%22]/div/div[1]/div/div/p[2]%27"
Here is the complete list of ASCII Encoding http://www.w3schools.com/tags/ref_urlencode.asp
You need to escape them; usually you write (inside HTML files) double quotes first, then single quotes (the opposite in .js files, but that's my personal style); whenever you need the same in between you need to escape it.
Example:
document.getElementById("some").innerHTML = "<img src='something' onmouseover='change(\"ex1\")' />";
Notice that using the JavaScript escape character (\) isn't enough in an HTML context; you need to replace the double-quote with the proper XML entity representation, ".
Example:
Do It!
In your case, I would recommend to URL encode "the URL" though.

Too many quotes within quotes -- what to do?

Here is a section of code used by CKEditor on my website:
CKEDITOR.config.IPS_BBCODE = {"acronym":{"id":"8","title":"Acronym","desc":"Allows you to make an acronym that will display a description when moused over","tag":"acronym","useoption":"1","example":"[acronym='Laugh Out Loud']lol[/acronym]", ...
If you scroll to the right just a little, you will see this:
"[acronym='Laugh Out Loud']lol[/acronym]"
I need to store all of the CKEditor code inside a javascript string, but I can't figure out how to do it because the string has both " and ' in it. See the problem? Furthermore, I don't think I can just escape the quotes because I tried doing that and the editor didn't work.
Any idea what I can do?
You might try taking the string and injecting JavaScript escape codes into it. JavaScript can essentially use any unicode value when using the format: \u#### - so, for a ' character, the code is \u0039, and for the " character, the code is \u0034.
So - you could encode your example portion of the string as:
\u0034[acronym=\u0039Laugh Out Loud\u0039]lol[/acronym]\u0034
Alternatively, you could attempt to simply escape the quotes as in:
\"[acronym=\'Laugh Out Loud\']lol[/acronym]\"
The problem here occurs when you wind up with this kind of situation:
"data:{'prop1':'back\\slash'}"
Which, when escaped in this manner, becomes:
"data:{\'prop\':\'back\\\\slash\'}\"
While this is somewhat more readable than the first version - de-serializing it can be a little tricky when going across object-spaces, such as a javascript object being passed to a C# parser which needs to deserialize into objects, then re-serialize and come back down. Both languages use \ as their escape character, and it is possible to get funky scenarios which are brain-teasers to solve.
The advantage of the \u#### method is that only JavaScript generally uses it in a typical stack - so it is pretty easy to understand what part should be unescaped by what application piece.
hmm.. you said you already tried to escape the quotes and it gave problems.
This shouldn't give problems at all, so try this:
$newstring = addslashes($oldstring);
There's no need to use Unicode escape sequences. Just surround your string with double quotes, and put a backslash before any double quotes within the string.
var x = "\"[acronym='Laugh Out Loud']lol[/acronym]\"";

Inject HTML to the end of webpage on iPhone using javascript

I have a UIWebView and I want to inject some HTML to the end of it after its been loaded.
NSString* javaScript = [NSString stringWithFormat:#"document.body.innerHTML += '%#'", arbitraryHTML];
[self.webView stringByEvaluatingJavaScriptFromString:javaScript];
The above code works, but only if arbitraryHTML is properly formated. E.g. the single quote ' is escaped as \'
I'd like to clean up HTML in genearl so that I can pass it to a javascript function.
What are other characters that I need to escape or strings that could cause problems?
Here's an example of some HTML that breaks the above code:
<span><a onmouseover=\\\"jQuery\\'# >Test</a></span>"
Can this be done in genearl? What else am I missing?
Thanks!
You need to make sure the JS engine does not throw up. So you need to escape single quotes and backslashes. This should do the trick:
arbitraryHTML = [[arbitraryHTML
stringByReplacingOccurrencesOfString:#"\\" withString:#"\\\\"]
stringByReplacingOccurrencesOfString:#"'" withString:#"\\'"]];
Note that you also need to escape backslashes inside Objective-C strings as seen above.
Turns out that its not enough to escape just the single quote character. I also needed to escape /n and /r to make this work with all HTML in general.
There may be some other character that I missed, if I find a case I'll post it.

Generic way to Escape Quotes in Javascript Variable

I have a form where users can enter any HTML.
var title = "Cool Check This"
As you can see, the variable is having " but it can be also '. It causes an error if there is ". What is better way to fix this? Storing escaped string in database like below?
$title = str_replace('"', "'", $_REQUEST['title']); // Replace double quote with single quote as js variable above is wrapped with double quotes.
Or escape it before showing on page? Anything in jQuery like escape that can help here?
var title="Cool Check This"
Well, you cannot escape it using JavaScript because JavaScript needs to see what you want to escape and you want to escape that. If you use PHP, you can use addslashes() prior to inserting into JavaScript.
Anyways, you should be careful of allowing to insert any HTML. Wrongly escaped HTML (like allowing to insert <script>) can allow to do various dangerous stuff, like stealing all cookies.

Categories