It’s easy to understand why Salesforce has emerged as the platform of choice for companies of essentially every type. Many of Salesforce's key products have become the industry standard. But another key benefit of Salesforce is the ability for developers to write custom code and apps to fit their business needs. Custom development with Salesforce's proprietary language Apex is often used to extend both built-in functionalities of the platform and also allows for 3rd party integrations via packages.
When working with custom Lightning apps or Digital Experiences (often referred to as Lightning Communities), custom Lightning Components are the most common way to add new functionality. Often, these custom communities and apps are publicly exposed to the internet, allowing customers and/or partners to interact with an organization. A common example is a customer success portal with the ability for customers to create cases when they have an issue with a product. Another example that has emerged in recent months are sites designed to let the public schedule COVID vaccination appointments.
Lightning Components offer an unlimited amount of functionality and are one of the huge benefits of the Salesforce platform. However, the caveat when it comes to custom development is the possibility of introducing security vulnerabilities within Apex code, which may then be exploited by a malicious actor. These vulnerabilities could lead to the exposure of sensitive data, modification of data, or destruction of data.
It’s important to note that by default, Salesforce's built-in Lightning Components and the underlying Apex code are very secure. However, it is always the responsibility of the client organization to ensure that any custom additions or modifications made to Salesforce adhere to security best practices, which have been extensively detailed in readily available documentation provided by Salesforce.
As an Offensive Security Engineer at AppOmni, I frequently see Salesforce environments that become compromised due to security vulnerabilities introduced through custom apps and experiences. If you are a developer writing custom Apex code, or a security practitioner in charge of overseeing the security of custom components, here are my key recommendations.
Common security issues
- The most common vulnerabilities found in the underlying Apex of Lightning Components are 'Missing Object/Field level security, and insecure sharing,' 'SOQL injection,' and 'Blind SOQL injection.'
- Missing Object/Field level security and insecure sharing is the most prevalent issue across custom Apex classes. Prior to the Spring'21 release, all Apex classes that are not declared as having 'with' or 'without' sharing default to 'without.' As a result, record information that normally is not accessible can potentially be accessed. This update demonstrates Salesforce's ongoing commitment to a 'secure by default' approach. In relation to Object and Field access, Salesforce provides various Apex methods and clauses that may be utilized by developers to ensure that permission checks are performed prior to granting access to data.
- The underlying Lightning Component code is written in Apex. These components communicate over the "Aura" API, which anyone can communicate with. As a result, any vulnerabilities can potentially be exposed to the anonymous internet. In addition, any 'Aura Enabled' method belonging to an Apex class of a Lightning Component becomes accessible to the public, not just those with direct access to the component itself.
- Lightning Components, when utilizing the Aura component programming model, are effectively a bundle of several files. The 'Server-Side' controller contains the Apex code and has its source code hidden from the public. However, the 'Controller JS' and 'Helper JS' live on the client-side. These files provide a rough guideline on how one may communicate with a Lightning Controller's Apex code without needing to interact with any UI elements. This can be done leveraging only a browser and a tool to proxy and relay HTTP requests such as Burp Suite.
- Regardless of how a Lightning Controller is implemented (via Experience Builder or Custom Lightning App), the methodology and process are effectively the same. Built-in (as in, exist in every Salesforce instance) Apex controllers are leveraged to retrieve the necessary information to manually craft calls to the server-side Apex code via the Aura API. This effectively emulates the background calls that are normally made when legitimately interacting with a Lightning Component via the UI.
- The 'Salesforce Object Query Language' (or SOQL) is leveraged to query record information in the backend. This is similar to SQL; however, it’s restricted to retrieving information since it does not support DML operations. This means the overall potential impact of an SOQL injection attack is less than that of SQL injection. Nonetheless, it's commonly utilized within Lightning Components to retrieve user-specific information. If developers do not sufficiently sanitize their SOQL queries in Apex, a user may have the ability to return record information for other users.
- Object and Field level checks do not sufficiently protect from SOQL injection, so the security of SOQL queries must be handled differently. Blind SOQL injection is a sub-category of vulnerability, in which information within a record is determined typically through an indirect indicator in the query response.
- Businesses should be utilizing static code analyzers, or 'SCA' for short, to catch security issues in code at early stages of the software development lifecycle (SDLC).
- Privileged components will always exist to perform administrative functionality. It is essential to have visibility into which users/personas within your Salesforce environment can access these components. This will allow for a reduction in attack surface through granular permission validation.
Securing custom development has never been more important. Development teams are tasked with creating powerful custom capabilities and are pushing out software faster than ever. To keep up, security needs to shift left – or earlier in the development cycle – to leverage DevSecOps for Salesforce's Apex code.
Aaron Costello is the Offensive Security Engineer at AppOmni.