📢 Attention Salesforce Certified Trailblazers! Maintain your credentials and link your Trailhead and Webassessor accounts by April 19th. Learn more.
close
•
Start tracking your progress
Trailhead Home
Trailhead Home

Create Secure Lightning Components

Learning Objectives

After completing this unit, you’ll be able to:

  • Describe component structure HTML/markup tags and expression language.
  • Identify expression language security points of failure.

Component Rendering

Note

Note

At the end of the last unit, we showed you how to get a Kingdom Management developer org. You need this org to complete the challenge in this unit, so if you don’t have it yet, go back and sign up for it.

Going from Lightning code to a stylized interactive UI takes a lot of work! The Lightning framework does a lot of it for you, though. Lightning tracks the data that your application needs through its attributes and server calls. It populates that data in the scope of your component and resolves any expressions to produce a clean usable user interface.  

Because Lightning handles data from the outside world, you must take steps to ensure the security of your component’s markup. Let’s walk through these steps.

HTML/Lightning Markup

One of the best things about Lightning is that it lets you use common web technologies. Aura components are built with extended HTML, CSS, and JavaScript, so you can use your existing knowledge to develop new applications quickly, and integrate them securely with Salesforce.

To integrate HTML, CSS, and JavaScript with the Lightning platform, you define your component in Lightning markup. This involves a few steps. 

  1. Wrap your HTML in the appropriate containers: <aura:application> or <aura:component>.
  2. Allow Lightning Experience to manage your resources for you by replacing <script> or <style> with <ltng:require>.
  3. Display dynamic data with the <aura:outputText> and <aura:outputRichText> tags.

Here’s an example of Lightning markup for the time-honored Hello World program.  

  <aura:component implements="flexipage:availableForAllPageTypes" access="global"> <ltng:require scripts="{!$Resource.myJavaScriptLib}"/> 
    <div class="main-content"> 
      <aura:outputText value="Hello World!">
    </div> 
  </aura:component>

Dangerous Tags

The Lightning platform is flexible and powerful. But with great power comes great responsibility. Used incorrectly, some of Lightning’s features can get you into trouble. 

Let’s look at a particularly powerful tag: <aura:unescapedHTML>. The value of this tag is interpreted as raw, unescaped HTML, which can alter your page significantly. We provide the <aura:unescapedHTML> tag to output preformatted HTML from a trusted source, and that’s the only way you should use it.

Where would you use raw HTML? Maybe you’re providing flexible styling for dynamic data and you want to specify styles in HTML. You build custom styling HTML for data in a controller, prefill the data into a styling string, and then render it as HTML in  Aura. Lightning automatically encodes data rendered between HTML nodes. (For example, <span>{!"Here"}</span>.) In order to prevent Lightning from encoding your data, you place it within an <aura:unescapedHTML> tag. That way it can run as code.

Pretty powerful, right? When you use this tag, you change the way Lightning works. In this case, you’re disabling a layer of protection. Now you’re responsible for providing that protection. Be careful when you disable any form of protection, and think about whether you want to do it. If Lightning isn’t guarding your data, you have to rely on other methods to secure your data and your code. 

Do You Need All of That Power?

Sometimes you don’t need to sacrifice protection to get what you want. For example, you can use <ui:outputRichText> to output stylized text without dealing with raw HTML. Read about this tag and others in the Lightning Components Developer Guide.

Unescaped HTML in Action

Now you’re rolling your eyes. We get it. Executing raw HTML as code is pretty neat. And right after we showed you how to do something cool, we told you not to do it! We don’t like being told what to do either. And because showing is better than telling, we’re going to show you what can happen when you invite unescaped HTML into your component. Get thee to the Kingdom Management developer org!

Note

Note

Remember, this module is meant for Lightning Experience. After you log into your Kingdom Management org, switch to Lightning Experience to do these steps and complete the challenges.

  1. . In your Kingdom Management developer org, on the left side of the navigation bar, click App Launcher, then select the Secure Lightning app.
    App Launcher Screenshot
  2. Navigate to the Unescaped HTML Demo tab.
    • You see a page that lists mythical beasts (Creature__c). Search for “wyvern.” The application shows you information about the wyvern and highlights its name with a <b> tag.
  3. Now search for “Balrog.”
    • Something strange happens. The Balrog’s battle cry changes the way the page displays. The Balrog’s code uses the <aura:unescapedHTML> tag, which renders all HTML passed to it without checking it.

The Balrog isn’t a magical record. The only thing that makes it special is that its description includes the string marquee. When this string is rendered as HTML, it moves elements around the page. Fortunately, LockerService prevents raw HTML from doing anything worse—the most an attacker can do is change data and the way it’s displayed. LockerService prevents cross-site scripting and similar attacks.

How can we protect our page against the malicious Balrog? We change the page to use <ui:outputRichText> to render our data. This tag supports the standard stylings you see in most applications but prevents malicious scripts and tags from affecting the page.

<ui:outputRichText value="{!v.creatures}"/>

Lightning Expressions

With Lightning expressions, you can do calculations and access object data within component markup. We use expressions to pass values between components and to output dynamic data.

An expression is any set of literal values, variables, subexpressions, or operators that can be evaluated to a single value. Method references are allowed, but calling those methods is not. Here are some examples of valid Lightning expressions:

  • {!"Hello world"}
  • {!v.myAttribute}
  • {!c.myControllerFunction}
  • {#v.myUnboundAttribute}

Anything inside the {! } or {# } delimiters is evaluated and replaced when the component is rendered or when it uses the value. Unbound attributes are designated by {# } and do not update if the underlying object or attribute has changed.

Here’s an example that uses a component attribute for the title of a division element.

  <aura:component> 
    <aura:attribute name="divTitleValue" type="string" />
      <div title="{!v.divTitleValue}"> 
        Div Example 
      </div> 
    </aura:component>

Secure Your Expressions

The Lightning expression language is pretty secure in most situations. For starters, Lightning automatically escapes any data you access through an expression.

Lightning expressions get some of their inherent security from the way they are built: They can only be compiled into node values or attribute values. No other situations compile. By restricting how expressions are constructed, Lightning saves you a lot of trouble by preventing expressions from contributing to security vulnerabilities. 

For example, this code snippet fails to compile because of two lines. The first of these lines, marked NOT OK, attempts to use an expression to construct part of an attribute value, which is forbidden: an expression must define an entire attribute. The second “NOT OK” line attempts to assign an expression to an HTML attribute name, which is not allowed—expressions can be only text values or attribute values.

<aura:component> 
  <aura:attribute name='var1' type='String'/>
  <div title="{!'title:' + v.var1}">test</div> <!--OK-->
  <div title="title:{!v.var1}">test<div> <!--NOT OK-->  
  <div title="{!v.var1}">test</div> <!--OK-->
  <div {!v.var1}="hello">test</div> <!--NOT OK-->
  <div>test:{!v.var1}</div> <!--OK-->  
</aura:component>

But Lightning expressions aren’t perfectly secure—they don’t protect you when you combine them with some HTML tags. If an href or src tag refers to an expression, a user can be redirected to an unsavory location. Look at  what happens in this component by reading the code comments.

<aura:component> 
  <aura:attribute name="val1" type="String">
  <a href="{!v.val1}">click</a>  //potentially unsafe: could go to any page 
  <iframe src="{!v.val1}"/> //potentially unsafe: could go to any page 
</aura:component>
Note

Note

A Lightning attribute has a type such as “String” or “Account,” but there’s no guarantee that the attribute’s value actually matches that type. JavaScript’s dynamic typing lets any data type inhabit an attribute. Insidious! Always check that an object (or Lightning attribute) has the properties you are trying to access, and that the data is what you expect.

Let’s see what happens when we use an “href” attribute unsafely. 

  1. In the Kingdom Management developer org, on the left side of the navigation bar, click App Launcher, then select the Secure Lightning app.
    App Launcher screenshot
  2. Navigate to the Unsafe Href Demo tab.
  3. You see a page that lists regions (Region__c) in the land. Search for “underworld.”
    • Welcome to the underworld. On this page, you see links to the most common creatures that inhabit it. The underworld has no content which is unsafe in this instance, and you should be safe no matter which link you click. The “unsafe” link may error out but you will remain in salesforce.
  4. Now search for another region, “The rolling hills.”

The rolling hills is home to a different set of creatures. The most common creature, the very-well-named Common Monster, has a link that is unsafe. If you click this link, you go to a music video, even though the object field structure and help text don’t say anything about leaving Salesforce. You don’t get any warnings about leaving Force.com, either—you’re just transported elsewhere.

However you feel about music videos, this is a vulnerability that we must fix. Let’s do it. 

  1. Verify that the data from “Region__c.Common_Monster__c” is actually an Id. An Id contains only alphanumeric characters—if our data contains anything else, it’s not a valid Id and we reject it.
  2. Now we turn our valid Id into a link using a Lightning expression.

Unsafe:

<a href="{!v.region.Common_Monster__c}">Common monster</a>

Why not just add a slash “/” before v.region.Common_Monster__c in the expression?

Safe:

<a href="{!'/'+v.region.Common_Monster__c}">Common monster</a>

Search for “The blind forest” region, and notice that the expressions beginning with “/” can still redirect a user out of Salesforce. In this case, the first (unsafe) Common monster link sends the user to that music video again. You will see the second link is safe because we sanitized the Id in v.safeCommonMonster before creating the link. We can make all of our links safe by using v.safeCommonMonster.

Unsafe:

<a href="{!'/'+v.region.Common_Monster__c}">Common monster</a>

Safe:

//JavaScript: we add a check for only alphanumeric and numeric values 
var alphaNum = /^[0-9a-zA-Z]+$/; 
if(results[0].Common_Monster__c.match(alphaNum)) { 
component.set('v.safeCommonMonster',results[0].Common_Monster__c); 
} 
Markup: 
<a href="{!'/' + v.safeCommonMonster}">Common monster</a>

Now we understand why sanitizing the ID and properly controlling the location makes the link safe.

Expressions Provide Security to a Point

Clearly, using Lightning expressions can enhance the security of your component. However, they are not a magic security solution. Make sure the output for your href is “Id” compliant—that is, it contains only alphanumeric and numeric characters.

Now you know what secure code looks like in Lightning Components. What about secure JavaScript code? That’s our next topic. 

Resources

What is the Lightning Component Framework?

Introducing LockerService for Lightning Components

Lightning Components Developer Guide: Writing Secure Code with LockerService

Lightning Components Developer Guide: ui:outputRichText

Note

Note

Remember, this module is meant for Lightning Experience. When you launch your hands-on org, switch to Lightning Experience to complete this challenge.

retargeting