Dust.js is a powerful JavaScript templating framework, currently maintained by LinkedIn, that can function both in the browser and server-side. At the moment, I’m working on an introductory presentation on Dust.js for the Silicon Valley Code Camp. And as I was working my way through the documentation, I found the coverage of filters rather sparse, so I spent some time playing with them and decided to write up what I found.
Dust.js templates work by binding a JavaScript object to a template in order to render output. The most basic element within a template is a key, which is a tag such as {name}. When bound to a JavaScript object that has a property called name, Dust.js rendering will replace the tag within the template with the value of the name property.
But what if that value derives from untrusted user input, or contains HTML mark-up, or needs to be included within a URL? In those cases, Dust.js provides a technique known as filters to escape the value.
Filter syntax is simple, just add the pipe symbol and a letter representing the filter to the end of the key tag. For example, {value|h}.
Lets now walk through each filter assuming in each case that we are passing to the Dust.js render function the object specified below:
var obj = {value: “<p><script>alert(‘xss attack’)</script></p>”};
To keep things interesting, I’ve included in the string property called value both html markup and JavaScript.
Default
If you write a key tag without specifying a filter, Dust.js will apply the default filter. The default filter replaces the angle brackets of html tags with html entities for proper display in the browser. This has the effect of thwarting cross site scripting attacks, as the browswer will render rather than execute the JavaScript. The default filter also replaces quotation marks denoting strings with JavaScript with html entities, again reducing the risk of xss attacks.
Template: {value}
Text Output:
Browser Display:
In most cases, the default will be the best choice, but it is important to understand the other filtering options for the special cases in which they make sense.
HTML Escaping |h
The html escape filter renders content with html markup such that it appears in the browser as escaped html. It basically double escapes the html. As a result, the ampersands in the default output are replaced with their html entity equivalent (&);
Template: {value|h}
Text Output:
Browser Display:
JavaScript Escaping |j
The JavaScript escaping filter renders content so that it can safely be used within a JavaScript string. The escaping prevents the output from breaking out of quoted strings and from breaking the closing </script> tag. This looks like the default filtering, except that the quotation marks are escaped with back slashes.
Template: {value|j}
Text Output:
Browser Display:
URL Escaping |uc, |u
URL escaping renders content usable within a URL by replacing all characters not allowed by the URL specification with % and their ASCII hexadecimal equivalent code.
The |u filter passes the content through the JavaScript method encodeUR(), and the |uc filter passes content through encodeURIComponent(). The method encodeURI() expects a URL that begins with http:// and will not escape this section of the URL. In contrast, encodeURIComponent() will escape all of the content.
Template: {value|uc}
Text Output:
Suppress Escaping |s
The simplest filter to understand is suppression (|s), which turns off escaping. This allows even JavaScript code to execute as part of the page, a risky approach that should be used only with fully trusted content. Adding the output of the following tag to a page will result in an alert window.
Template: {value|s}
Text Output: <p><script>alert(‘xss attack’)</script></p>
Brower Display:
why does |h double escape? Is that a bug?
Thanks for the tips. They’ve been helpful.
Thank you so much for those clear explanations ! dustjs doc is not that good.