Day 2: Avoid Cross-site Scripting (XSS) using ColdFusion 10 – Part 1

"Cross-site scripting (XSS) is a type of computer insecurity vulnerability typically found in Web applications (such as web browsers through breaches of browser security) that enables attackers to inject client-side script into Web pages viewed by other users. A cross-site scripting vulnerability may be used by attackers to bypass access controls such as the same origin policy. Cross-site scripting carried out on websites accounted for roughly 80.5% of all security vulnerabilities documented by Symantec as of 2007.[1] Their effect may range from a petty nuisance to a significant security risk, depending on the sensitivity of the data handled by the vulnerable site and the nature of any security mitigation implemented by the site’s owner." – Wikipedia

In ColdFusion 10 added bunch of functions to avoid XSS attack, XSS attack (as explained above by Wikipedia) is some scripting code/iFrame in dynamic content which will render in webpage and significantly create security risk. Most of us already using HTMLEditFormat to encode user input (like comment in blog post) to avoid unwanted HTML rendering. But HTMLEditFormat is not capable to avoid all kind of XSS attack since this function encode only <, >, & and ". This function will not help if you to avoid XSS in tag attribute, CSS and JavaScript. ColdFusion 10 introduce endcodeForHTML, encodeForHTMLAttribute, encodeForJavaScript, endCodeForURL and canonicalize to fight with XSS attach. In this post I will try to cover some of them.

encodeForHTML

Encodes the input string for use in HTML and returns encoded String. 
Below is sample code trying render HTML content variable stored in ColdFusion variable. Let’s assume variable value coming through user input (may be comment on blog post) which will be displayed in blog comment area right below post.

[code:cf]<cfsavecontent  variable="htmlcontent">
<div>
Here is <i>test</i> html content includes<br/>
<script>alert(‘hello’)</script>
Notice how &amp; rendered with both functions.
</div>
</cfsavecontent>
<cfoutput>#htmlcontent#</cfoutput>
<hr/>
<cfoutput>#htmleditformat(htmlcontent)#</cfoutput>
<hr/>
<cfoutput>#encodeForHTML(htmlcontent)#</cfoutput>[/code]

 

And here is output…

I have tried to annotate and highlight to distinguish changes. 
<cfoutput>#htmlcontent#</cfoutput> is most dangerous statement when you are rendering direct input from user. Notice that ‘test’ displayed in italic and script doesn’t rendered instead "hello" will be alerted on browser. Means we are opening all doors for attacker for XSS attach. There can be any dangerous script instead of alert(‘hello’).
Second output statement look good and it displayed HTML code instead of rendering HTML output on screen but doesn’t render properly already encoded & since htmlEditFormat function simply encode <, >, & and " characters without know what your content is.
encodeForHTML is smart, it knows what already encoded in HTML and what not. Also this function is not limited to encode fix number of characters instead it encode almost all non alphanumeric characters.

encodeForHTMLAttribute

encodeForHTML will not always work to avoid XSS attack. encodeForHTMLAttribute can be use if you using coldfusion variable to be rendered through html tag attribute. Below sample code where I try to show how dangerous it can be if we are not doing proper encoding.
[code:cf]<cfset attrValue="Male"" onclick=’alert(""script executed on click"")’">
<cfoutput>
Without using encoded for HTML Attribute
<input type="text" name="gender" value="#attrValue#"/><br/>
<hr/>
With encoded Attribute
<input type="text" name="gender" value="#encodeForHTMLAttribute(attrValue)#"/><br/>
</cfoutput>[/code]

Here is generated HTML output
[code:html]Without using encoded for HTML Attribute
<input type="text" name="gender" value="Male" onclick=’alert("script executed on click")’"/><br/>
<hr/>
With encoded Attribute
<input type="text" name="gender" value="Male&quot;&#x20;onclick&#x3d;&#x27;alert&#x28;&quot;script&#x20;executed&#x20;on&#x20;click&quot;&#x29;&#x27;"/><br/>
[/code]

Look at first input tag code, it look like there is onclick event on text field which will fire some JavaScript code by clicking on text and user will never realize that some JavaScript code executed as he can see on "Male" as value of text field. But in second one user will whatever actual value was in ColdFusion variable.
 

encodeForJavaScript

This function will encode text for use in JavaScript. As we have seen in above two samples, in many places we may need to use coldfusion variable to generate JavaScript content. Let’s go through sample code to explain how this function is really useful.
 [code:cf]<cfoutput>
<cfset divcontent = "Hello <b>World</b>’; alert(‘script executed through JavaScript xss’);//">
<div id="ex1"></div>
<script>
document.getElementById("ex1").innerHTML=’#divcontent#’;
document.getElementById("ex1").innerHTML=’#encodeForJavaScript(divcontent)#’;
</script>
</cfoutput>[/code]
Simple JavaScript code that change HTML with content stored in coldfusion variable and here is generated HTML content.
[code:html]
<div id="ex1"></div>
<script>
document.getElementById("ex1").innerHTML=’Hello <b>World</b>’; alert(‘script executed through JavaScript xss’);//’;
document.getElementById("ex1").innerHTML=’Hello\x20\x3Cb\x3EWorld\x3C\x2Fb\x3E\x27\x3B\x20alert\x28\x27script\x20executed\x20through\x20JavaScript\x20xss\x27\x29\x3B\x2F\x2F’;
</script>[/code]

Look at the first statement in script tag. This will only Hello World in div content and alert in browser (and can be any dangerous script call here). Now have a look on second statement where we use encodeForJavaScript function it encode text and make safe to render under script tag also it make sure that word "World" appear bold in div content.
I guess ColdFusion use well known ESAPI to implement all this security function. I will cover some more security functions tomorrow’s post.

Hope this help.