Given a scenario, prevent user interface and data access security vulnerabilities.

After studying this topic, you should be able to:

  • Identify the different types of security vulnerabilities in Salesforce applications
  • Determine the recommended techniques and practices to protect users from security attacks
  • Analyze various business scenarios and identify how to prevent security vulnerabilities

Table of Contents

  • Introduction
  • SOQL Injection
  • Cross-Site Request Forgery
  • Cross-Site Scripting
  • Controlling Data Access
  • Securing Sensitive Data
  • Unescaped Values in Visualforce Pages
  • Scenarios and Solutions

Introduction

  • This page describes the most common security vulnerabilities for applications on the Salesforce platform
    • Salesforce provides built-in portection against several types of security risks, but developers need to take advantage of Salesforce’ security features and implement proactive measures to protect custom applications from potential security attacks depending on the requirements and customization involved.
    • Application security flaws can result in manipulation or exposure of Salesforce data
    • Programmatic techniques for preventing security vulnerabilities are covered on this page
  • Most common security attacks/risks that custom applications developed using Apex and Visualforce can be vulnerable to:
    1. SOQL injection
    2. Cross-Site Scripting (XSS)
    3. Cross-Site Request Forgery (CSRF)
    4. Data Access Control Issues
    5. Third-Party Content Issues

SOQL Injection

  • SOQL Injection: SOQL injection is a technique that is used to inject values to manipulate the construction and outcome of a dynamic SOQL query
    • SOQL only supports SELECT keyword, not UPDATE or DELETE, which protects SOQL from most attacks
    • Method or approach used in traditional SQL injection are very similar to SOQL injection
  • Salesforce recommends the following techniques for preventing SOQL injection attacks
    • Bind Variables: an input can be enforced to be treated as a variable and not an executable part of the query
    • Typecase Variables: variables are casted according to their respective data types (e.g., Boolean, Integer) to intentionally throw exceptions when unexpected data types are encountered
    • Escape Single Quotes: An escape character can be added to all single quotation characters using String.escapeSingleQuotes() to ensure that the strings are not treated as commands
    • Allowlist Variables: if possible user input values are known, the input value should be checked against that defined list, or an allowlist. Also, a NOT NULL check should be avoided
    • Sanitize Input: also known as restricted list, this approach involves removing potential bad characters from user input
  • SOQL Injection Example: The following demonstrates a Visualforce page for searching partner accounts based on user input received from a form

  • Escape Single Quotes Example: The below illustrates how the escapeSingleQuotes method adds escape slashes to a string value

Cross-Site Request Forgery

  • Cross-site request forgery (CSRF) performs an action via a URL that takes advantage of the active session of an authenticated user
  • Considerations regarding protection from CSRF:
    • Built-in Protection: default protection built in that validates a token
    • Action Types: possible action types are create a record, send email, log a call, custom Visualforce, update a record, Lightning component, and flow
    • Avoid state changes: developers can ensure built-in protection is used by avoiding state changing operations
  • Salesforce implements built-in anti-CSRF tokens in all its standard controllers and methods
    • Request Validation: before executing a command, Salesforce automatically checks this hidden token to verify the authenticity of the page request
    • Custom Controllers: custom controllers can become vulnerable to CSRF attacks
  • The following shows the built-in CSRF protection configuration in Setup

  • The following Visualforce page is used to delete a contact by passing the id of the record to delete in the URL. This example in its current state is vulnerable to CSRF attacks

  • For example, an attacker can create a web page that contains the element below. When a logged-in org user lands on this web page, a request to the Visualforce page will be made on behalf of the user

  • To protect the page against CSRF, for example, the controller’s delete logic should be removed from the init action and placed in an action method that is not automatically run when the page loads

Cross-Site Scripting

  • Cross-site scripting (XSS) is when malicious content such as JavaScript / VBScript / HTML is inserted into a web page and executed
    • User Session: script can take advantage of the user’s session and use it to submit transactions, read data, or alter the page using HTML/CSS
  • Considerations regarding protection from XSS:
    • Input Filters: Checking user input against defined values
    • Output Encoding: Ensuring that only the appropriate characters are displayed
    • Apex Tags: All standard Visualforce components, which start with have anti-XSS filters in place
    • Output Filters: Salesforce has implemented filters that screen out harmful characters in most output methods as one of the anti-XSS defenses
  • One example of cross-site scripting is a Visualforce page that receives user input via the URL:

  • Then, an attacker can supply the “text” URL parameter with a malicious image tag and render it on the Visualforce page

  • onerror event can be prevented by encoding the output coming from Apex. The String class comes with HTML escape and unescape methods.

Controlling Data Access

  • Data Access Control: Apex classes execute in system modeand may expose sensitive data to unintended users
    • Full Access: Apex does not enforce user permissions and field level security, granting full access to records
    • With Sharing: Using the with sharing keyword ensures that the permissions of the currently logged in user are used
    • Inherited Sharing: The inherited sharing keyword can be specified on an Apex class to allow the class to run in the sharing mode of the class that called it
      • Apex class that uses the inherited sharing keyword runs as with sharing when used as a Visualforce page controller, Apex REST service, or an entry point to an Apex transaction
    • Lightning Components: @AuraEnabled Apex classes used by Aura components or Lightning web components that do not specify with sharing or without sharing will default to with sharing to ensure that Lightning components are secure by default
    • Omitted Declaration: If an Apex class is used as the entry point to an Apex transaction, an omitted sharing declaration runs as without sharing. Using the inherited sharing keyword ensures that the default is to run as with sharing
    • Explicit Declaration: Using an explicit inherited sharing declaration makes the intent clear, avoiding ambiguity arising from an omitted declaration or false positives from security analysis tooling
    • WITH SECURITY_ENFORCED: The WITH SECURITY_ENFORCED clause, which enforces field and object level security permissions, can be added to a SOQL statement which will cause the query to throw a System.QueryException if the current user does not have access to a field or object that is referenced in the SOQL statement
    • SECURITY.STRIPINACCESSIBLE: The Security.stripInaccessible Apex method can be used to remove fields from SOQL query results that the current user does not have access to and avoid exceptions when a DML operation is performed.
  • WITH SECURITY_ENFORCED Example: This clause applies security checks in the SELECT or FROM SOQL clauses but not on WHERE or ORDER BY clauses. So, a query can be filtered, for example, using a field that the user does not have access to

  • Security.stripInaccessible() Example: An AccessType enum value is specified when using the method to indicate the type of field-level access check to perform. Valid enum values are CREATABLE, READABLE, UPDATABLE, and UPSERTABLE

  • Enforcing Object and Field Permissions: Object-level and field-level permissions can be enforced through code by explicitly using sObject and field describe result methods:
    • Object-Level:
      • isAccessible() - returns true if current user can access the object
      • isCreateable() - returns true if current user can create records of the object
      • isUpdateable() - returns true if current user can update records of the object
      • isDeletable() - returns true if current user can delete records of the object.
      • Ex: check if user has Delete permission on Lead object: Schema.sObjectType.Lead.isDeletable()
    • Field-Level:
      • isAccessible() - returns true if current user can access the field of a record.
      • isCreateable() - returns true if current user can set the value of the field for a new record.
      • isUpdateable() - returns true if current usercan update the value of the field for an existing record
      • Ex: check if user can update the Company field on the Lead: object:Schema.sObjectType.Lead.fields.Company.isUpdateable()
  • Example method that performs preliminary object-level and field-level permission checks. Describe information can be retrieved either from a Describe result or through a token.

  • Using WITH SHARING Keyword: Visualforce below will access records using the sharing rules of the current user

  • Using INHERITED SHARING Keyword: following Apex class (custom Controller) has inherited sharing

  • Secure Retrieval and Display of Third-Party Content: Visualforce provides methods to safely display third-party content on the page
    • Image Content: When a Visualforce page loads a third-party image outside the org’s server, it can initiate a malicious authentication request meant to stealSalesforce usernames and passwords
    • IMAGEPROXYURL Function: The IMAGEPROXYURL function can be used to securely retrieve images and protect users from unauthorized requests
    • Using IMAGEPROXYURL: The IMAGEPROXYURL function can be included on the ‘src’ attribute of a tag or the ‘value’ attribute of an apex:image object
    • HTML Content: HTML static resources can be isolated on a separate domain using iframes to protect Visualforce content from untrusted sources
    • $IFRAMERESOURCE: A static HTML file can be referenced on a separate domain by using $IFrameResource.<resource_name> as a merge field, where resource_name is the name of the uploaded static resource
  • Following shows how to safely display an external image on a Visualforce page

  • Visualforce pages can be displayed on trusted external domains using iframes by allowing it in Session Settings in Setup

Securing Sensitive Data

  • Securing Sensitive Data: Salesforce provides multiple options for securing sensitive data such as passwords, encryption keys, OAuth tokens, etc
    • Declarative Options: Sensitive data can be stored using the declarative features: protected custom metadata types, protected custom settings, encrypted custom fields, and named credentials
    • Programmatic Option: Data can be programmatically secured through encryption and decryption using methods provided by the Crypto Apex class
      • encrypt() and decrypt(): These methods are used when encrypting and decrypting data using a custom initialization vector
      • encryptWithManagedIV() and decryptWithManagedIV(): These methods are used for encrypting and decrypting data using an initialization vector (IV) generated by Salesforce
  • Following shows an example that uses the AES (Advanced Encryption Standard) algorithm to encrypt and decrypt data

Unescaped Values in Visualforce Pages

  • Visualforce Page Outputs and Formulas: Visualforce components with escape attribute set to false or formula expressions evaluated outside a Visualforce component display unfiltered values and pose a security risk

  • Displaying Unfiltered Values on a Page: Here are two examples of how displaying unfiltered values on a Visualforce page exposes vulnerability to cross-site security attacks

  • Escaping Unfiltered Values: Salesforce offers the following functions that can be used on the Visualforce page to escape potentially insecure output
    • HTMLENCODE: This function encodes text and merge field values to be used in HTML by replacing reserved HTML characters with their HTML entity equivalents
    • JSENCODE: This function encodes text and merge field values to be used in JavaScript by inserting escape characters before unsafe JavaScript characters
    • JSINHTMLENCODE: This function is a combination of the HTMLENCODE and JSENCODE functions where the former will be executed first and then the latter
    • URLENCODE: This function encodes text and merge field values for use in URLs by replacing illegal characters in a URL with code to represent them based on RFC 3986

  • Escaping Unfiltered Values Examples: To display secure values, the escape attribute in Visualforce components that support it should be set to true. Also, the necessary functions should be used accordingly such as illustrated below

  • No Protection from XSS: here are two areas where Salesforce does not implement built-in XSS protection. This is to allow execution of JavaScript code that is actually intended by the developer.

Scenarios and Solutions

Reference FoF Slides