Let the platform do the work

XSS Prevention

Overview

This document describes how to prevent cross-site scripting (XSS) attacks in Sugar customizations. XSS attacks occur when malicious entities are able to inject client-side scripts into web pages.

Best Practices

When creating custom code for Sugar, be sure to respect the following best practices. These rules serve to protect the elements of your customizations that are most susceptible to XSS vulnerabilities:

  • Create safe variables when injecting HTML via Handlebars templates or JavaScript methods such as: $(selector).html(variable), $(selector).before(variable), or $(selector).after(variable).
  • Avoid using triple-bracket (e.g. {{{variable}}}) syntax to allow unescaped HTML content in Handlebars templates.
  • Never use input from an unknown source as it may contain unsafe data.
  • Protect dynamic content, which may also contain unsafe data.

Please refer to the following sections for more information and examples that demonstrate these best practices.

Creating Safe Variables

You must always encode a variable before you inject or display it on a webpage. The piece that is not encoded should be isolated and marked as a safe string very carefully. The the following sections outline protecting your system when using JavaScript and Handlebars templates.

JavaScript

To ensure displayed JavaScript variables are safe, respect these two rules:

  • If you are displaying plain text without any HTML, use .text() instead of .html() with your selectors.
  • If your text contains HTML formatting, you can use .html() as long as it does not contain any dynamic data coming from a variable.
Vulnerable Setup

This is an example of bad code because it utilizes the .html() method to display a dynamic-value variable, leaving the JavaScript vulnerable to injection:

var inputData = $('#myInput').val(); // "<script>alert(0)</script>"
$(selector).html('This is the value: ' + inputData); // "This is the value: <script>alert(0)</script>"
Protected Setup

This is an example of good code, which uses the safe .text() method to protect the JavaScript from potential injection:

var status = 'safe';
$(selector).text('This is very ' + status); // "This is very safe"

This is also an acceptable approach, which uses the Handlebars.Utils.escapeExpression to safely escape the content:

var inputData = $('#myinput').val(); // "<script>alert(0)</script>"
var safeData = Handlebars.Utils.escapeExpression(inputData); // "&lt;script&gt;alert(0)&lt;/script&gt;"
$(selector).html('This is the value: ' + safeData); // "This is the value: &lt;script&gt;alert(0)&lt;/script&gt;"

Handlebars Templates

Handlebars, by default, handles the encoding of data passed to the template in double brackets (e.g. {{variable}}), however, it also allows you to bypass this encoding by using triple brackets (e.g. {{{variable}}}). Text passed via triple brackets will not be encoded. As a rule, do not use triple brackets. If you don't want Handlebars to encode a piece of a string, use double brackets and execute Handlebars.SafeString() in your JavaScript controller. 

As an example, we will apply best practices to a complex use case with dynamic values that need to be encoded. For this example, we want to display a message similar to:

Congrats! You just created the record <a href="/#Accounts/abcd">ABCD</a>

The values ABCD and /#Accounts/abcd are dynamic values and, therefore, must be encoded. But the message must also be displayed as HTML, so the overall element cannot be entirely encoded. To address this use case, we must properly script the JavaScript controller and the Handlebars template.

The following JavaScript encodes the message's dynamic values, marks the displayed hyperlink as a safe string, and then outputs the safe message:

var record = {
    id: 'abcd',
    name: 'ABCD'
};

// escape `ABCD`
var safeName = Handlebars.Utils.escapeExpression(record.name);

// escape `abcd`
var safeId = Handlebars.Utils.escapeExpression(record.id);

// Mark the link as a SafeString now that the unsafe pieces are encoded and the content has safe HTML.
var link = new Handlebars.SafeString('<a href="/#Accounts/' + safeId + '">' + safeName . '</a>');

// This can be displayed with double brackets in the template because html parts will not be encoded.
this.safeMessage = new Handlebars.SafeString('Congrats! You just created the record ' + link + '.');

To display the safe message in the application, use the following syntax in your Handlebars template:

<div class="success">{{safeMessage}}</div>

Please refer to the HTML Escaping documentation on the Handlebars website for more information. 

Topics