I have Google Charts uploaded as static resource which I'm using in a lightning component. The component also has 3 different tabs (https://www.lightningdesignsystem.com/components/tabs/), based on which tab the user selects, I'm exploding the pie slice on the chart -- which will essentially redraw the Google Chart. Will this be flagged in security review?

Thanks in advance for your reply/suggestion(s)!

1 Answer 1


For specific questions like this, please book an office hour:

However, in general, there are Lightning apps out there that use charting libraries without issues, although I am not aware of one using Google Charts.

You will need to make sure your library (and all dependent code) is loaded from static resources using the Salesforce CDN rather than from a third party CDN. It is not enough to put a bootstrap loader into static resources that itself loads code from a third party endpoint. If you cannot do this, then put the chart in an iframe that is hosted on a null origin or a non-Salesforce origin.

For managed packages, code that is not managed by Salesforce and is not under the version control of the package version id can still be used in an offering but it can't run on an authenticated Salesforce origin. This is called a composite app. After all, it's code that can change at any time and is controlled by a third party. You as the vendor of a managed package cannot force your subscribers to have such a trust relationship with the third party even if you as the developer trust them. It's important to understand the security relationship between a managed package vendor and a subscriber is not transitive.

Assuming that the code is part of the package, since your chart is rendering to the DOM, if you are using it in the framework lifecycle then it should be called from the renderer. If you are working outside the framework lifecycle, then be sure that you unrender cleanly should your component be unrendered by the framework; remember that you are doing pluggable component based development, not page based development, so you have no control over when, how many times, or where your component is rendered/unrendered or updated. You need to write your code in a way that handles this type of hot pluggability/unpluggability. The framework does this for you by forcing you to divide your code into separate rendering/re-rendering/unrendering/controller methods, and then wires these methods up to the correct framework action, but if you work outside the framework you need to handle possible conflicts yourself. Also if you re-enter the framework from outside it, e.g. to pull data from Salesforce to put into the chart via a controller action, then do this with $A.getCallback().

The Lightning Developer Guide contains several tips and best practices to help you, but if you go down this path please make sure you have a good understanding of how the framework works. For this reason, it's recommended that you stay in the framework lifecycle and just render your chart from a renderer rather than from an afterScriptsLoaded event in the controller. For example, you can set an attribute that the chart is ready to render tied to an afterScripts loaded event handler, and then in your renderer check for this attribute and then draw the chart.

Next, be sure to provide the full unminified code. Neither the security review team nor the source scanner can process minified code and we need to be able to review all of the code in the package just as all of the code needs to be under the package version configuration management. Again, if you must use code for which you do not have access to the unminified sources, then leave it out of the package and drag it in to a different origin as third party code in a composite app. Note that I'm not saying that you can't serve minified code, only that unminified versions of all minified files need to be included in static resources for the security team to review.

Finally, it should go without saying that you can't have any cross site scripting vulnerabilities in your charts. Unfortunately most js based charting libraries use raw html rendering functions for everything from chart labels (and sometimes even chart data!) to chart titles. If you are pulling these from unsafe data types on the server or setting these as aura attributes, then you will have issues unless you htmlencode the labels or other chart decorations.

Lightning does not currently provide any html encoding library now provides encoding functions such as $A.util.sanitizeHtml​ that you can use to sanitize variables in your javascript code. If your chart labels are pulled from aura:attributes, then be aware that lightning does not have expression sanitizer functions such as Visualforce's HTMLENCODE to auto-sanitize attributes, so you will need to write your own interception and encoding logic to make sure that your code sanitizes the labels before it passes them to the chart rendering logic from the attribute. Be aware that because of the auto-binding, your attributes can change at any time and so you are responsible for reliably intercepting any attribute change and performing sanitization before your attribute value is passed to your library. This could be done with a aura:valueChange event handler wired to the unsafe attribute so that your code does the proper sanitization and then loads the attribute value to the chart. If your chart metadata is only loosely bound to aura:attributes (it is not refreshed in a re-render event), then you only need to worry about the initialization stage and don't need to handle attribute value changes, although in this case you might be breaking some expected component contracts. Again, the amount of sanitization needed depends on which attributes are rendered as HTML in the Google Charts library and which are rendered as text. Please consult the documentation, but in many cases you will need to examine the source, which is another reason why you need access to unminified source code and also why it's important to control the source code being loaded at runtime.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .