Showing posts with label salesforce. Show all posts
Showing posts with label salesforce. Show all posts

Securing Salesforce Apps – A Real-World Story with ACME

In the previous blogs, we saw how different vulnerabilities are discovered, resolved and can have impact on the application from the code perspective. In this blog, we walk you through a real world scenario where ACME, a client is using a Salesforce-based application for client onboarding. ACME stores sensitive user data which makes it important for them to implement access controls to guarantee that only authorized team members are able to carry out authorized tasks and view users' personally identifiable information (PII). The application was created to provide a safe and effective onboarding process while streamlining Know Your Customer (KYC) procedures.  

However, handling financial and PII data is not something to be taken lightly. The involvement of sensitive information like personal identification, account statements, and books requires utmost attention. Although Salesforce provides a secure platform to build secure and agile applications, the access control and configuration of the platform is where the real challenge lies. Simply put, even the most secure system is only as safe as its setup.

At this point, ACME realized that they needed a thorough security review, everything from code to Salesforce configurations, and turned to Blueinfy. This blog is aimed at providing a detailed take on how we carried out the security review for ACME and ensured the platform’s reliability. 

The Role of Blueinfy in ACME’s Journey

The main goal of Blueinfy was to make the ACME application and configuration as secure as possible. Our approach was not limited to code reviews and penetration testing for identifying underlying issues. Typically, that’s the way to go; however, Salesforce has its own unique setup that can expose businesses to risks if not addressed properly.

As a result, we decided to kick up the security review by a notch by moving ahead of the usual tests and performing a detailed configuration review. To help the app seamlessly handle the financial data with confidence, we aimed to further strengthen ACME’s foundation.

What the Review Actually Covered

Instead of highlighting the technical jargons, let’s quickly discuss the key areas and checkpoints we covered that made all the difference.

1. Access Management – User Roles, Profiles, Permission Sets

As the name suggests, we started working on the application’s core by reviewing who can access the Salesforce platform, alongside all the interactive resources and functionalities at the user level. To prevent unauthorized access for the safety of sensitive data, effective access management is crucial.

Salesforce provides a unique way to set up user roles, profiles, and permission sets to implement access management, which allows you to decide who has access to different Salesforce components, i.e., records, objects, and fields. Moreover, it also defines the level of access (read, write, delete, etc.) each user has. 
 

It is important to understand the following terms in the context of the Salesforce application configuration-

  • Roles – It helps in determining a user’s position in the org and affects access to records based on the default organization-wide settings. 
  • Profiles – Determines the authorization to perform an action (Create, read, update, and delete) on objects and fields
  • Permission Sets – a list of permissions that need to be granted to users in addition to their profile 
During the Blueinfy review, one of the key focus of the testing was to review user roles and profile setup to identify permission implementation. For example, a non-admin user should not have access to change any system-wide settings. The objective here was also to make sure that ACME is following the principle of least privilege and is granting only the user’s permissions that are necessary. The review team exploited authorization bypass vulnerabilities at many instances due to missing CRUD/FLS enforcement in the code, despite access restrictions being defined through profiles and permission sets.

 

2. Sharing Settings

In Salesforce, sharing settings define how records are shared within the organization. When the application has multiple users and user roles, it is essential to implement platform-provided protection to implement proper authorization. This control ensures that users can only access the data appropriate to their role. 

The sharing settings also configure external organisation-wide defaults, which give control/manage access of external users. When this setting is configured as “Public Read/Write,” it permits all external users to view and modify each record of that object. Blueinfy reviewed ACME’s implementation of sharing settings to ensure proper implementation of authorization. The objective here was also to make sure that ACME is following the principle of least privilege to protect the data of the application against unauthorized access, especially for external users. 

 

3.  Insecure Storage of Sensitive Data 

Ensuring sensitive data is kept securely was a critical component of this review. Moreover, it assists in safeguarding against data breaches and protects the data from unauthorized users. The Salesforce platform provides multiple secure storage options with protected custom metadata API fields. It boasts custom settings, named credentials, and encrypting data in custom objects with keys in protected custom settings. To make sure that no data is stored as plain text, Blueinfy’s evaluation assessed ACME’s use of the Salesforce-supplied encryption mechanism, verifying its proper use. Moreover, the entire application was only accessible over a secure channel (SSL).  

 

4. Wide OAuth Scope

Salesforce often provides a wide third-party app support. However, this brings along the risk of more access than necessary. Protocols like OAuth enable the application to access Salesforce data on behalf of a user. This makes the system vulnerable, as broad scopes can unknowingly provide applications with more data than they require. Blueinfy carefully reviewed the OAuth configurations for ACME’s integration. Here, our main goal was to grant minimal access to external applications. Hence, we took all the narrowly defined common scopes, including Full Access, API Access, and Refresh Tokens, in ACME’s Salesforce environment into consideration and were successfully able to reduce the risk of data leakage by restricting the OAuth scope. Our practice helped in ensuring that only necessary data and functionality were exposed to external systems. 

 

5. Session Management

Session management refers to the controls that decide the duration of a user session and system behavior on user inactivity. Improperly configured session timeout may cause unauthorized access if a session is active for a long time, or users may get logged out early, causing inconvenience. Blueinfy made sure that ACME set the session timeouts correctly so that it reduces the risks of session hijacking and more.

 

6. Password Policies

Strong passwords are still the first line of defence. Even cloud platforms like Salesforce can fall victim to brute-force attacks with weak or predictable passwords. To prevent such instances and unauthorized user access, Blueinfy made sure that ACME’s application is aligned with industry best practices to protect user accounts from common threats. 

 

7. Missing Security Headers

Web applications rely on security headers for functions including protection against HSTS, clickjacking, content injection, and other common issues. Applications can be vulnerable to these threats when security headers are absent or incorrectly set. Blueinfy verified the presence of essential security headers in ACME’s Salesforce application.

Key Takeaways from the Review

Our testing methodologies allowed us to make significant practical improvements. From reducing excessive permissions and refining data-sharing rules to setting stricter login controls, Blueinfy did not just reduce hidden risks for ACME but also provided a clearer picture of the application’s functioning. 
This resulted in making the ACME’s Salesforce application more compliant and genuinely more secure. More importantly, ACME’s team could now serve clients knowing that their information was well-protected.

The Bigger Picture: Why This Matters for Businesses

For any business that handles financial or personal data, a simple overlooked configuration can result in costly breaches and distrust among consumers. This highlights the point that security reviews should not be seen as nice, optional extras, but rather as a necessity for growth. By acting proactively, ACME created an opportunity instead of a problem and improved its system and client assurance. 

ACME’s experience teaches every company that uses Salesforce or other similar platforms an important lesson: a secure and stable platform requires attention and expertise to point out certain misconfigurations. Salesforce has strong built-in protections, but how these parameters apply depends entirely on the configuration of the platform.
 

Understanding Cross-Site Scripting and SOQL Vulnerabilities in Salesforce

Salesforce has remained a popular choice for CRM platforms. From customizing workflows to building applications, businesses can seamlessly achieve their goals with this cloud-based platform. What’s more, the extended functionality, like Visualforce pages, Lightning Web Components (LWC), Aura Components, and Apex, aids development for the enterprises significantly. 
 
We saw few vulnerabilities and security controls provided by Salesforce platform in past couple of blogs. We are going to discuss about two more common and severe vulnerabilities - Cross-Site Scripting (XSS) and SOQL Injection in this blog. 

Cross-Site Scripting (XSS) in Salesforce

XSS occurs when an application takes untrusted user input and returns the response containing user input without encoding to the browser. Attackers take this opportunity to run malicious JavaScript in the victim’s browser and extract sensitive information.
 
In Salesforce, XSS can appear in:
  • Visualforce Pages: Using raw {!} expressions without escaping.
  • Aura Components / LWC: Unsafe DOM manipulation or improper attribute use.
  • JS Controllers:  Unvalidated data is passed straight into the user interface.
 
How to Detect XSS in Code
  • Unescaped Output in Visualforce → Flag <apex:outputText value="{!userInput}" escape="false"/> or direct use of {!userInput} without proper encoding
  • Improper aura:unescapedHtml in Aura → Any use of aura:unescapedHtml or dynamic attributes directly rendering user data
  • Direct innerHTML assignment in LWC/JS → Using element.innerHTML = userInput instead of textContent. Moreover, the usage of insecure JavaScript functions such as html(), eval()
  • Input Fields Without Validation → Inputs accepted from users (comments, descriptions, messages) should be validated or sanitized before use
Vulnerable Example in Salesforce
 
Visualforce Page (Vulnerable):
<apex:page controller="XSSExampleController">
       <apex:form>
           <apex:inputText value="{!userInput}" label="Enter your name:"/>
           <apex:commandButton value="Submit" action="{!processInput}"/>
           <br/>
           <!-- Directly rendering user input -->
           <apex:outputText value="{!userInput}" escape="false"/>
       </apex:form>
</apex:page>

Controller:
public class XSSExampleController {
       public String userInput {get; set;}
       public void processInput() {
           // No validation or sanitization here
       }
}

If the attacker enters, <script>alert('XSS Attack!');</script> attack vector it will execute in the victim’s browser. 

Safe Example
 
Visualforce Page (Safe):
<apex:outputText value="{!userInput}" escape="true"/>

By default, escape value is true. 
Or manually encode:
<apex:outputText value="{!HTMLENCODE(userInput)}"/>

In LWC, avoid assigning user input directly to innerHTML/html():

// Vulnerable
element.innerHTML = userInput;

// Safe
element.textContent = userInput;


Impact
By exploiting XSS vulnerability, an attacker can steal user session. Once an attacker gets access to user session, he can perform tasks on behalf of the user which can result in data loss. In other cases, an attacker can redirect user to phishing site or can deface the application.


SOQL Injection in Salesforce 

 
What is SOQL Injection?
SOQL Injection is similar to SQL Injection in traditional applications. This occurs when the untrusted user input is directly combined into a dynamic SOQL query string. Once coupled, the attackers may be able to access unauthorized data or bypass restrictions by manipulating the query. 

How to detect in Code 
When reviewing Salesforce Apex code, focus on how queries are built:
  • Dynamic SOQL with Concatenation → Flag any use of Database.query() or string concatenation (+) with user-supplied input
String q = 'SELECT Id FROM Account WHERE Name = \'' + userInput + '\'';
Database.query(q);   
  • Red flag when user input (e.g., from ApexPages.currentPage().getParameters(), form fields, or API requests) is directly concatenated
String searchKey = ApexPages.currentPage().getParameters().get('search');
String query = 'SELECT Id FROM Contact WHERE Email LIKE \'%' + searchKey + '%\'';
List<Contact> contacts = Database.query(query);

Apex Controller (Vulnerable):
public with sharing class SOQLInjectionExample {

        @AuraEnabled(cacheable=true)
        public static List<Account>searchAccounts(String inputName) {
// VULNERABLE: direct string concatenation
String query = 'SELECT Id, Name FROM Account WHERE Name LIKE \'%' + inputName + '%\'';
             return Database.query(query);       
         }
}

Here, an attacker could supply input like,
test%' OR Account LIKE '
This would alter the query to return all accounts, bypassing intended restrictions.

Secure Code in Apex:
  • Safe queries use bind variables (:variable) instead of concatenation.
String searchKey = ApexPages.currentPage().getParameters().get('search');
List<Contact> contacts = [SELECT Id, Name FROM Account WHERE LIKE :('%' + inputName + '%')];

  • Verify Input Validation and Escaping - even with dynamic queries, Salesforce provides String.escapeSingleQuotes() to neutralize malicious input.
String userInput = ApexPages.currentPage().getParameters().get('name');
userInput = String.escapeSingleQuotes(userInput);
String query = 'SELECT Id FROM Account WHERE Name = \'' + userInput + '\'';
List<Account> accList = Database.query(query);



Impact
Like any SQL Injection, a successful exploitation of SOQL Injection can result in data loss which will result in compliance violation and can cause damage to customer trust and reputation of the company.

 

Conclusion

Both XSS and SOQL Injection are serious vulnerabilities of Salesforce applications resulting from improper handling of user input. XSS works on the client side. This includes how data is rendered. Attackers use this to execute scripts within the user's browser. SOQL Injection works on the server side, allowing attackers to access Salesforce data by using an insecure query. We saw different vulnerabilities from the code perspective in these series of blogs. During the next blog, we will understand how a configuration review can help secure salesforce applications with a real-world example of one of our engagements. 

Understanding CRUD/FLS and Sharing Violation Vulnerabilities in Salesforce

Introduction

In the previous blog, we saw some of the vulnerabilities which we observe during Salesforce review. In this blog, we understand some of the security features provided by Salesforce platform and how can we leverage it to write secure code along with the method to detect insecure implementation. 
Salesforce requires developers to check object-level, field-level, and record-level permissions in their code.  Failure in addressing these issues could result in causing CRUD/FLS vulnerabilities, which ultimately can expose sensitive data to unauthorized users. 

CRUD/FLS Violation Vulnerability

What is CRUD/FLS?
CRUD (Create, Read, Update, Delete) terms whether a user is authorized to perform operations on an object like an account, contact, or opportunity.  FLS (Field-Level Security) determines whether a user can view or modify desired fields within an object, such as the Salary field in the Employee object.  Object (CRUD) and Field Level Security (FLS) are configured on profiles and permission sets and can be used to restrict access to standard and custom objects and individual fields. Force.com developers should design their applications to enforce the organization's CRUD and FLS settings on both standard and custom objects, and to gracefully degrade if a user's access has been restricted.

The CRUD/FLS violation is typically triggered when the Apex code fails to verify the user authorization before performing DML operations, querying objects, or fielding directly.


Insecure Apex Code Example

public class EmployeeController {
       @AuraEnabled 
       public List<Employee__c> getEmployees() {
           // No check for object-level or field-level security
           return [SELECT Id, Name, Salary__c FROM Employee__c];
       }

        @AuraEnabled 
        public void createEmployee(String name, Decimal salary) {
           // No check for Create access
           Employee__c emp = new Employee__c(Name = name, Salary__c = salary);
           insert emp;
       }
}


In this example:

  • A user without “View Salary” field access can still retrieve salary data.
  • A user without “Create Employee” permission can still insert a new record.

How to Detect in Code: 

During a manual code review, look for:

  • SOQL queries that directly select fields
  • DML statements (insert, update, delete, and upsert) executed without permission checks
  • Missing calls to Salesforce’s schema-based security methods:
  • Schema.sObjectType.ObjectName.isAccessible()
  • Schema.sObjectType.ObjectName.isCreateable()
  • Schema.sObjectType.ObjectName.isUpdateable()
  • Schema.sObjectType.ObjectName.isDeletable()
  • Schema.sObjectType.ObjectName.fields.FieldName.isAccessible()

 How to Fix in Code:
To rectify the problem, the code should effectively perform CRUD/FLS enforcement on both the object and the fields of the object. This will help the developer utilize various mechanisms based on the requirements and context of the application.

User Mode Execution – Apex code runs in System mode by default, which means that code will be executed with excessive permissions  regardless of the current user’s permissions. By allowing the User mode object and field-level permissions of the current user, the DML operation is performed. 
// Insert record with user-level permission checks
Database.SaveResult result = Database.insert (new Opportunity (Name = 'Big Deal', CloseDate = Date.today(), StageName = 'Prospecting'),
AccessLevel.USER_MODE
);


Traditional CRUD/FLS Enforcement Checks – isAccessible, isCreateable, isUpdateable, isDeleteable methods 
 

With Security Enforced – User’s object/field permissions are enforced by appending the “WITH SECURITY_ENFORCED” keyword in the SOQL query.  This keyword is only allowed to check permissions for read operations. 

// Enforces both CRUD and FLS at query time
List<Contact> cons = [
       SELECT Id, FirstName, LastName, Email
           FROM Contact
           WITH SECURITY_ENFORCED
];

 Note:  When the “WITH SECURITY_ENFORCED” keyword is used, the API version should be 48.0 or later. Additionally, this keyword does not support traversal of a polymorphic field’s relationship and TYPEOF expressions with an ELSE clause in queries.

Using stripInaccessible() – The stripInaccessible() method helps to enforce CRUD/FLS by removing the fields from query and subquery that users do not have access to.  This method  checks user’s access based on their field-level-security  for a specified operation – create, read, update, and upsert. 

List<Account> accounts =  [SELECT Id, Name, Phone, Email FROM Account];
// Strip fields that are not readable
SObjectAccessDecision decision = Security.stripInaccessible (AccessType.READABLE, accounts);
List<Account> sanitizedRecords = (List<Account>) decision.getRecords();



Impact
CRUD and FLS always need to be enforced for create, read, update, and delete operations on standard objects. In the vast majority of cases, CRUD and FLS should also be enforced on custom objects and fields. Any application performing creates/updates/deletes in Apex code, passing data types other than SObjects to VisualForce pages, using Apex web services or the @AuraEnabled” notation should be checked that it is calling the appropriate access control functions.

In the past, due to incorrect implementation of CRUS/FLS in application, we have observed that an employee can gain unauthorized access to personnel data or payroll information of everyone in the organization OR in customer support applications, weak CRUD checks allow agents to modify or delete records beyond their assigned accounts.

There is business and compliance risks involved when the proper enforcement of CRUS/FLS permissions are not in place. Such weaknesses can ultimately result in data breaches, regulatory penalties, financial loss, and reputational damage. 

Sharing Violation Vulnerability

What is Sharing in Salesforce?
Salesforce enforces record-level security through sharing rules,  determining which records a user can access. Apex classes run in the following modes:

  • With Sharing – Enforces record-level sharing rules of the logged-in user.
  • Without Sharing – Ignores record-level sharing rules and runs in system context, potentially exposing all records. A sharing violation occurs whenever Apex code runs without respecting the current user's record-level sharing rules.
  • Inherited Sharing – Declaring class will enforce (inherit) the sharing rules of the calling class.

 

Insecure Apex Code Example
public without sharing class AccountController {
       @AuraEnabled
       public List<Account> getAccounts() {
           // Returns all accounts, even those the user should not see
           if (Schema.sObjectType. Revenue__c.isAccessible() &&
               Schema.sObjectType. Revenue__c.fields.Name.isAccessible()) {
           return [SELECT Id, Name, Revenue__c FROM Account];
           }
       }
}


In this example, even if sharing rules restrict the user to accounts in their region, the class will return all accounts in the system. Even if CRUD-FLS permissions are checked before performing the query, it will still return all accounts. This is because CRUD-FLS permissions ensure field-level security, while sharing rules ensure record-level access.


How to Detect in Code
During a code review, look for:

  • Classes declared as without sharing.
  • Classes with no explicit sharing declaration (default is without sharing if not specified in a class used as an entry point).
  • DML operations and Queries returning sensitive records without additional filtering.


Secure Apex Code Example
public with sharing class AccountController {
       @AuraEnabled
       public List<Account> getAccounts() {
       if (Schema.sObjectType. Revenue__c.isAccessible() &&
               Schema.sObjectType. Revenue__c.fields.Name.isAccessible()) {
                  return [SELECT Id, Name, Revenue__c FROM Account];
           }
       }
}


If a class must operate in system mode (e.g., batch jobs, admin tasks), developers should:

  • Explicitly justify the use of without sharing.
  • Apply programmatic filters to enforce access (e.g., filtering records based on owner or custom sharing logic).

Impact

The Force.com platform makes extensive use of data sharing rules. Each object can have unique permissions for which users and profiles can read, create, edit, and delete. These restrictions are enforced when using all standard controllers. When using a custom Apex class, the built-in profile permissions and field-level security restrictions are not respected during execution. The default behaviour is that an apex class has the ability to read and update all data within the organization. Because these rules are not enforced, developers who use Apex must take care that they do not inadvertently expose sensitive data that would normally be hidden from users by profile-based permissions, field-level security, or organization-wide defaults. This is particularly true for Visualforce pages.

In the past, due to insecure implementation of sharing, we have observed vulnerabilities like, sharing violation exposes medical records, insurance details, or financial information to unauthorized staff, resulting in HIPAA, GDPR, or PCI DSS violations OR in sales environments, sales executive might get access to opportunities in another territory OR a support agent gets an access to cases belonging to another client.  

In regulated settings, this could allow unauthorized users to get access to personal financial and healthcare information, resulting in privacy breaches, regulatory non-compliance, and fines. When we have sharing violations, they are more than just a compliance issue. They create a lack of trust among the partners. They also disrupt the flow of business activities. Even more, they expose competitive data. Finally, all this leads to customers losing their trust and some reputational harm.

Conclusion

Salesforce platform provides CRUS/FLS and sharing implementation as a key feature to implement security and permissions however the most common vulnerabilities are inappropriate implementation of CRUD/FLS and Sharing Violation in the Salesforce application. To mitigate these risks, developers should take care of the below: -
  • Before executing any query or DML operation, always check the CRUD and FLS permissions.
  • Classes should be declared “with sharing” by default unless you have a good reason to bypass sharing rules.
  • Do manual code reviews along with automated scans to ensure that the security controls are implemented.
In the next blog, we will understand XSS and SOQL vulnerabilities in Salesforce platform.

Salesforce Applications: Importance of Performing a Security Review

Salesforce has remained a top choice for enterprises when it comes to building applications. Thanks to its flexibility, scalability, and rich set of features, organizations can build applications tailored to their workflows seamlessly. But then again, a question arises: Do I need to worry about security if I write the application on salesforce platform?

A common misconception that the app is secure often comes up when businesses develop apps or customizations on the platform. And the answer is, “Yes” (reasons for the same are well described in another blog entry under “The Importance of Security Reviews for Applications on Enterprise Platforms” Even though Salesforce offers a robust and secure platform, it is your responsibility to secure your own custom code, configurations, and integrations.

Salesforce Application Overview

The applications built with Salesforce are normally structured across two core layers with a unique purpose. However, these layers also tend to introduce potential security considerations. 

  • Client-Side (User Interface Layer): As the name implies, the client-side layer that can be implemented in many frameworks is responsible for managing user interactions with the application.  Visualforce Pages is an older, page-based framework for creating user interfaces with business logic embedded inside. Aura Components and interface creation are great tools, but the mishandling of attributes and methods can pose security-related issues. Lightning Web Components (LWC) represent Salesforce’s modern, standards-based framework. In LWC, web components are used to enhance performance. Moreover, these components also offer strong security.  
  • Server-Side (Business Logic Layer): The application’s business logic, data processing are typically implemented on server-side layer. Salesforce programming language is Apex which is similar to Java. Apex code is mainly used for database operations, process and business rules implementation. Even though Apex code provides wide range of capabilities to build a business logic, the use of improper and unsafe coding at this layer may lead to serious security risks.  These layers definitely make the Salesforce applications flexible and scalable. However, they create multiple entry points that can cause security vulnerabilities if not checked or secured properly.

The Significance of Security Reviews

Salesforce undergoes rigorous security testing and compliance. Based on the requirements, either you, your team, or a partner develops custom apps, Apex code, Visualforce pages, Lightning, and integrations. If there are any flaws in any of the layers, attackers could gain access to Salesforce org, go through private client data, or raise compliance issues.

In other words, Salesforce ensures the platform security, while the application team must ensure the security of what they have built on the platform.

Choosing the Right Salesforce Testing Method: Black-Box vs. White-Box

When reviewing a Salesforce app, one can choose between - 

  • Black-box testing is the process of when the tools simulate an attack as if they were an outside attacker, without any prior knowledge. This helps to find issues such as injection points, misconfigured endpoints, and authentication problems.
  • White-box testing refers to the practice whereby the tester has full access to the code/configuration/metadata. This technique often reveals logical errors, dangerous storage, bad sharing policies, and API misuse that black-box analysis wouldn’t usually detect.

A combination of the two is the best strategy. The internal aspect of the configuration and logic is secured as a result of the white-box test. The black-box test verifies the attack surface externally.

Security Concerns to Take into Account in Salesforce

Understanding specific risks that go beyond those of conventional web applications is necessary when scoping a Salesforce security review. Here is the list of some of them - 

  • CRUD/FLS Bypass – if Create, Read, Update, Delete, or Field-Level Security checks are not performed properly, it may leak sensitive data.
  • Insecure Sharing Settings/Sharing Violation – Access to restricted records can be unintentionally shared if the code is running without sharing. 
  • SOQL Injection –. If user inputs are directly passed in SOQL queries (without any processing or validation) it can lead to data leakage due to SOQL query manipulation. 
  • Cross-Site Scripting (XSS) –   Fail to validate user inputs in Visualforce, Aura, or LWC can lead to XSS attack.
  • Open Redirects – Phishing or session hijacking can become very common if the JavaScript functions and PageReference redirections are used without validation.
  • Hardcoded Secrets in Apex / Insecure Storage of Sensitive Data – Credentials, tokens or sensitive information are stored in plaintext as part of the code or in configuration or database.
  • Sensitive Data in Debug Logs – if System.debug() is set, an administrator can get access to sensitive data by accessing logs of the application. 
  • Wide OAuth Scope – While integrating Salesforce with third party applications, typically OAuth protocol is used. In the implementation of OAuth, if OAuth scope is set to full instead of necessary requirement, it will allow third party applications to access excessive data and functionality of Salesforce. 
  • Insecure CORS Configuration – One can exploit weak implementation of CORS to make calls to Salesforce APIs.
  • Overexposed APIs – Sensitive data can be exposed if the application fails to restrict appropriate use of Salesforce APIs.

The Significance of Configuration Review and Permissions

Manual pen testing and code review go a long way in ensuring that security parameters are up to the mark but there are multiple permission settings and incorrectly configured security controls that can compromise even the most secure code. Examining Salesforce's permission model is just as crucial as running code tests:

  • Profiles and Permission Sets – Make sure users only have access to what is require.
  • Role Hierarchy and Sharing Rules – Avoid exposing too many private documents.
  • Field-Level Security (FLS) – Prevent unauthorized users from reading or altering sensitive fields.

Misconfigurations in these areas are one of the most common sources of breaches in Salesforce environments.

Conclusion

In conclusion, Salesforce platform provides a secure foundation, but the additional layers, functionalities and customization on the platform need to be reviewed to make sure that the security controls provided by Salesforce platforms are implemented correctly. To build a secure application, the focus of the review should be on platform specific vulnerabilities and use of secure coding best practices along with the classic web application vulnerabilities.  The combination of black-box, white-box along with deeper permission and configuration review will make sure that the application is secure. 

We are going to write about the key vulnerabilities we normally discover while performing salesforce security review in our next entry. 

Performing Security Code Review for Salesforce Commerce Cloud Application


Salesforce Commerce Cloud (SFCC), formerly known as Demandware, is a robust cloud platform tailored for building B2C e-commerce solutions. It offers a reference architecture, the Storefront Reference Architecture (SFRA), which serves as a foundational framework for website design. SFRA is carefully designed to act as a blueprint for developing custom storefronts. Given your familiarity with this platform, we will forego an extended introduction to Commerce Cloud. Instead, let's review some fundamental concepts before proceeding to the code review.

Access Levels
The platform offers -

  • Developer Access: For users involved in the development of storefront applications, this access level permits the creation of new sites or applications and the deployment of associated code.
  • Administrator Access: Primarily used for managing global settings across all storefront applications within the SFCC system. This level also enables "Merchant Level Access".
  • Merchant Level Access: Allowing users to manage site data (import/export), content libraries, customer lists, products, and marketing campaigns.

SFRA Architecture
SFRA typically includes an "app_storefront_base" cartridge and a server module. These components can be used with overlay plugin cartridges, LINK cartridges, and custom cartridges to create a cartridge stack for layering functionalities. A typical cartridge stack might look like this:

Source: https://developer.salesforce.com/

SFRA employs a variant of the Model-View-Controller (MVC) architecture. In this setup:

  1. Controllers handle user input, create ViewModels, and render pages.
  2. ViewModels request data from B2C Commerce, convert B2C Commerce Script API objects into pure JSON objects, and apply business logic.

The "app_storefront_base" cartridge includes various models that utilize the B2C Commerce Script API to retrieve data necessary for application functionality. These models then construct JSON objects, which are used to render templates.

In SFRA, defining an endpoint relies on the controller's filename and the routes specified within it. The server module registers these routes, mapping URLs to the corresponding code executed when B2C Commerce detects the URL. Additionally, the server module provides objects that contain data from HTTP requests and responses, including session objects.


Cartridge
In B2C Commerce, a "cartridge" serves as a modular package for organizing and deploying code, designed to encapsulate both generic and application-specific business functionalities. A cartridge may include controllers (server-side code where business logic is implemented), templates, scripts, form definitions, static content (such as images, CSS files, and client-side JavaScript files), and WSDL files. Typical base cartridge architecture:

Source: https://developer.salesforce.com/

SFCC Security
One of the key advantages of using platform-built applications is the inherent security provided by the platform. However, it is essential to ensure that configurations enhancing the security of the code are properly applied during implementation. To broadly review the security of a Salesforce Commerce Cloud application, consider the following pointers:


Encryption/Cryptography
In Salesforce, including B2C Commerce, the "dw.crypto" package is commonly used to enable developers to securely encrypt, sign, and generate cryptographically strong tokens and secure random identifiers. It is crucial to review the usage of classes within this package to ensure they meet security standards. For instance, the following classes in "dw.crypto" are considered secure: -

  1. Cipher - Provides access to encryption and decryption services using various algorithms.
  2. Encoding - Manages several common character encodings.
  3. SecureRandom - Offers a cryptographically strong random number generator (RNG).

However, the below classes suggest the use of deprecated ciphers and algorithms, and may introduce vulnerabilities: -

  1. WeakCipher
  2. WeakSignature
  3. WeakMac
  4. WeakMessageDiget

Declarative Security via HTTP Headers 

Certain HTTP headers serve as directives that configure security defenses in browsers. In B2C applications, these headers need to be configured appropriately using specific functions or files. HTTP headers can be set through two methods: -

  1. Using the "addHttpHeader()" method on the Response object.
  2. Using the "httpHeadersConf.json" file to automatically set HTTP response headers for all responses.

To ensure robust security, review the code to confirm the presence of important response headers such as Strict-Transport-Security, X-Frame-Options, and Content-Security-Policy etc.
 

Cross-Site Scripting / HTML Injection
B2C Commerce utilizes Internet Store Markup Language (ISML) templates to generate dynamic storefront pages. These templates consist of standard HTML markup, ISML tags, and script expressions. ISML templates offer two primary methods to print variable values: -

  1. Using "${...}": Replace the ellipsis with the variable you want to display.
  2. Using the "<isprint>" tag: This tag also outputs variable values.

When reviewing .isml files, it is crucial to examine the usage of these tags to identify potential vulnerabilities such as Cross-Site Scripting (XSS) or HTML Injection. These vulnerabilities allow attackers to inject malicious client-side scripts into webpages viewed by users. Example of vulnerable code: -

Script Injection
Server Script Injection (Remote Code Execution) occurs when attacker-injected data or code is executed on the server within a privileged context. This vulnerability typically arises when a script interprets part or all of unsafe or untrusted data input as executable code.
The "eval" method is a common vector for this type of vulnerability, as it executes a string as a script expression. To identify potential risks, review the code for the use of the global method "eval(string)", particularly where the string value is derived from user input.
 

Data Validation
In addition to the aforementioned security checks, it is crucial to validate all user input to prevent vulnerabilities. This can be achieved through functions like "Allowlisting" (whitelisting) and "Blocklisting" (blacklisting). Review these functions to ensure proper input and output validations and to verify how security measures are implemented around them.
 

Cross-Site Request Forgery
Salesforce B2C Commerce offers CSRF protection through the dw.web.CSRFProtection package, which includes the following methods: -

  1. getTokenName(): Returns the expected parameter name (as a string) associated with the CSRF token.
  2. generateToken(): Securely generates a unique token string for the logged-in user for each call.
  3. validateRequest(): Validates the CSRF token in the user's current request, ensuring it was generated for the logged-in user within the last 60 minutes.

Review the code to ensure that these methods are used for all sensitive business functions to protect against CSRF attacks.
 

Storage of Secrets
When building a storefront application, it is crucial to manage sensitive information such as usernames, passwords, API tokens, session identifiers, and encryption keys properly. To prevent leakage of this information, Salesforce B2C Commerce provides several mechanisms for protection: -

  1. Service Credentials: These can be accessed through the "dw.svc.ServiceCredential" object in the B2C Commerce API. Ensure that service credentials are never written to logs or included in any requests.
  2. Private Keys: Accessible through the script API using the "CertificateRef" and "KeyRef" classes. Utilize these classes to manage private keys securely.
  3. Custom Object Attributes: Customize attributes and their properties to use the type "PASSWORD" for storing secrets. This helps ensure that sensitive information is handled securely.

Review the code to verify that all secrets are stored using these methods and are not exposed or mishandled.
 

Authentication & Authorization
To ensure that business functions are carried out with appropriate privileges, developers can utilize certain pre-defined functions in Salesforce B2C Commerce: -

  1. userLoggedIn: This middleware capability checks whether the request is from an authenticated user.
  2. validateLoggedIn: This function verifies that the user is authenticated to invoke a particular function.
  3. validateLoggedInAjax: This function ensures that the user is authenticated for AJAX requests.

Review the code to confirm that these functions are used appropriately for any CRUD operations. Additionally, ensure that the code includes proper session validation checks for user permissions related to each action.
 

Redirection Attacks
In general, redirect locations should be set from the server side to prevent attackers from exploiting user-injected data to redirect users to malicious websites designed to steal information. To validate this, review the code for any instances where user input might be directly or indirectly sent to: -

  1. "<isredirect>" element: Used in ISML templates for redirecting.
  2. "dw.system.Response.redirect" object: Utilized to handle redirects in the script.

 

Supply Chain Security
The platform allows the use of various software sources through uploads, external linking, and static resources. However, this introduces the risk of including unwanted or insecure libraries in the storefront code. For SFRA implementations, ensure that the "addJs" and "addCss" helper methods use the integrity hash as an optional secondary argument to verify the integrity of the resources being added.
 

Secure Logging
Salesforce B2C Commerce logs are securely stored and accessible only to users with developer and administrator access. These logs can be accessed via the web interface or over WebDAV. To ensure the security of sensitive information, review the code to confirm that sensitive data such as keys, secrets, access tokens, and passwords are not logged. This is particularly important when using the "Logger" class. Ensure that sensitive information is not passed to any logging functions ("info", "debug", "warning") within the "Logger" class.
 

Business Logic Issues
Business logic issues can arise from various factors, such as excessive information revealed in responses or decisions based on client-side input. When reviewing SFCC code for logical vulnerabilities, focus on the following areas: -

  1. Reward Points Manipulation: In applications that add reward points based on purchases, ensure that the system validates the order number against the user and enforces that rewards are added only once per order. Rewards should also be deducted if an order is canceled or an item is returned. Failure to do so can allow users to manipulate reward points by passing arbitrary values as the order number.
  2. Price Manipulation: When submitting or confirming an order, verify that the final price of the product is calculated on the server side and not based solely on client-supplied values. This prevents users from purchasing products at lower prices by manipulating request data.
  3. Payment Processing: Since applications often leverage third-party payment gateways, ensure that calls to these gateways are made from the server side. If the client side handles payment processing, users might change order values. Review the logic to confirm that payment validation and processing occur server-side to prevent manipulation.
  4. Account Takeover: For password reset functionality, ensure that reset tokens are not sent in responses, that tokens cannot be reused, and that complex passwords are enforced. Avoid sending usernames from the client side for password resets to reduce the risk of account takeover.

Review the code for validation logic in each business function to uncover any exploitable scenarios resulting from missing or improper validations.
 

In a Nutshell
The above points highlight that, despite the robust security controls provided by the B2C platform, poor coding practices can undermine these protections and introduce security vulnerabilities into the application. It is essential not to rely solely on platform security features but also to conduct a thorough secure code review to identify and address potential issues in the implementation.
 

Useful Links

  • https://developer.salesforce.com/docs/commerce/sfra/guide/b2c-sfra-features-and-comps.html
  • https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-cartridges.html
  • https://osapishchuk.medium.com/how-to-understand-salesforce-commerce-cloud-78d71f1016de
  • https://help.salesforce.com/s/articleView?id=cc.b2c_security_best_practices_for_developers.htm&type=5

Article by Maunik Shah & Krishna Choksi