Understanding:
Locker Service is a powerful security architecture for Lightning components. Locker Service enhances security by isolating Lightning components that belong to one namespace from components in a different namespace. Locker Service also promotes best practices that improve the supportability of your code by only allowing access to supported APIs and eliminating access to non-published framework internals.
At a high level, Lightning Locker uses various technologies and techniques that are intended to do the following:
Prevent:
1. Components from causing XSS and similar security issues
2. Components from reading other component’s rendered data without any restrictions
3. Components from calling undocumented/private APIs
4. Enforces CSP(Content Security Policy), which is a security standard to protect against XSS, clickjacking and other code injection attacks.
Enable:
1. Cool new features like client-side API versioning similar to REST API versioning
2. Faster security review
3. Better and more secure JS development practices
4. Running 3rd party JS frameworks like React, Angular and so on
5. Easily adding or removing new security features and policies
6. In locker service, use of the eval() function is supported to enable use of third-party libraries that evaluate code dynamically. However, it is limited to work in the global scope of the namespace. The eval() function can’t access the local variables within the scope in which it is called, it will only evaluate variables that are defined in global namespace.
Note: The Eval function support which is limited now has quite a substantial effect on the usage of third-party libraries. Previously it was unrestricted, but now it is restricted to only global scope. To understand this better, lets see an example. Consider the following code:
With locker service disabled we see the following output:
Notice the value returned by the bar() function is the value of the local variable. But if we enable the locker service then the value of the local variable will not be evaluated i.e. the value of global variable will be displayed. Take a look at the output.
Locker service only allows usage of eval in global scope. Third-party libraries that use eval must be compliant with locker service. To check if your libraries are compliant with Locker service, you have to upload them in static resources and then check by using some functions of the library. If it is supported in locker service then, it will run without any issue, otherwise it will throw some error.
Enable Locker Service:
In Summer ’17, LockerService is auto-activated for all orgs with no option to disable.You can disable LockerService for a component by setting version 39.0 or lower for the component. If a component is set to at least API version 40.0, which is the version for Summer ’17, LockerService is enabled. When you create a component, the default version is the latest API version.
In Developer Console, click Bundle Version Settings in the right panel to set the component version. Take a look at the following to set the bundle version:
Without Lightning Locker Service:
1. Any JS of any component can call any JS functions of any other component as they are all loaded in the DOM
2. Any JS can also call any undocumented/private Lightning APIs
3. Any JS can access real DOM and get rendered data from other components.
4. Components that are not security reviewed can potentially have security issues.
With the Lightning Locker turned ON:
1. Salesforce-authored components and JS run in “System mode” (similar to the Operating System’s system mode) and have full access to everything.
2. Custom components run in “User mode” and don’t have access to the real Document or real “window” object.
3. Custom components instead gets a custom DOM (“secureDOM”), custom Window and so on.
4. Custom components can access other components’ DOM as long as they are in the same namespace but won’t be able to access other components’ DOM that are in different namespace.
Consider the following example:
We have a lightning component with lightning button and a div inside for the label. We want to see if the div which is in c namespace will be able to access the inner content of the lightning:button which is lightning namespace. Here is the code for the component:
Output:
The below image is when the Locker Service is turned off:
After the Locker service is turned ON, the output looks like:
Notice the inner html is now not accessible for the custom component java-script. Also notice that when the custom components’ JS tries to traverse the DOM by using div.parentNode.innerHTML, it does not get it.