How to Secure Your Salesforce Queries with String.escapeSingleQuotes

Nov 22, 2024


 

Introduction

In Salesforce development, writing secure and efficient code is crucial to protect against vulnerabilities like SOQL (Salesforce Object Query Language) injection. SOQL injection occurs when malicious data is injected into a query, potentially leading to unauthorized access or alteration of data. One of the simplest and most effective ways to safeguard against such vulnerabilities is by using the String.escapeSingleQuotes() method to escape user input.

In this blog, we will explore how to prevent SOQL injection using escapeSingleQuotes(), compare unsafe and safe methods for handling user input in queries, and show you how to run the code to observe the difference.

Understanding the Code

Let's break down the code example provided:

GetAccountsByName.apxc
public class GetAccountsByName {
    public static List<Account> getAccountsByNameUnsafe(String userInput) {
        String query = 'SELECT Id, Name FROM Account WHERE Name = \'' + userInput + '\'';
        System.debug('Unsafe query: ' + query);
        return Database.query(query); // Unsafe!
    }

    public static List<Account> getAccountsByNameSafe(String userInput) {
        String safeInput = String.escapeSingleQuotes(userInput);
        String query = 'SELECT Id, Name FROM Account WHERE Name = \'' + safeInput + '\'';
        System.debug('Safe query: ' + query);
        return Database.query(query); // Safe!
    }
}

 

Explanation of Methods

  1. Unsafe Method (getAccountsByNameUnsafe):

    • The method accepts a String userInput and directly injects it into the SOQL query without any sanitization.
    • The resulting query can be manipulated by a user who enters malicious data, allowing for SOQL injection.

    Example of dangerous user input: \' OR Name != \'

    If an attacker passes the above input, the query becomes:

    SELECT Id, Name FROM Account WHERE Name = '' OR Name != ''

    This could lead to unintended behavior, such as retrieving all accounts or bypassing conditions.

  2. Safe Method (getAccountsByNameSafe):

    • This method first escapes any single quotes in the user input by using the String.escapeSingleQuotes() function.
    • Escaping single quotes helps prevent any injected SQL code from altering the structure of the query, ensuring that the user input is treated as a string literal, not executable code.

    Example of safe user input: \' OR Name != \'

    The query becomes:

    SELECT Id, Name FROM Account WHERE Name = '\' OR Name != \''

    In this case, the single quote characters are safely escaped, and the query will function as expected without allowing injection.

 

The escapeSingleQuotes() Method

The String.escapeSingleQuotes() method in Apex is used to escape single quotes in a string. It's a simple yet powerful tool that ensures user input, which may contain special characters, does not interfere with the syntax of SOQL queries.

Here’s how it works:

This is a basic security measure that helps prevent SOQL injection attacks. Without it, malicious users could manipulate the query by injecting special characters like single quotes or SQL operators.

 

How to Run the Code

To test the code and observe the difference between unsafe and safe methods, follow these steps:

  1. Prepare User Input: Let's use the same potentially malicious input to test both methods.

    // Unsafe input
    String userInput1 = '\' OR Name != \'';
    // Safe input
    String userInput2 = '\' OR Name != \'';

  2. Call the Unsafe Method:

    List<Account> accountsUnsafe = GetAccountsByName.getAccountsByNameUnsafe(userInput1);
    System.debug('Unsafe: ' + accountsUnsafe);

    This will run the query with unsafe user input. If the input is manipulated correctly, the query might return unexpected results or cause errors.

  3. Call the Safe Method:

    List<Account> accountsSafe = GetAccountsByName.getAccountsByNameSafe(userInput2);
    System.debug('Safe: ' + accountsSafe);

    This will run the query with sanitized user input, escaping any single quotes to prevent injection.

  4. Observe the Results:

    • In the unsafe version, you might see unexpected or incorrect results.
    • In the safe version, the query will only return the correct results, and any injected SQL code will be neutralized.

 

Best Practices

While using String.escapeSingleQuotes() is an excellent safeguard, it's also important to follow other best practices for writing secure Apex code:

  1. Use Bind Variables: The safest way to prevent SOQL injection is to use bind variables instead of concatenating user input into queries. For example:

    public static List<Account> getAccountsByNameSafeBind(String userInput) {
        String query = 'SELECT Id, Name FROM Account WHERE Name = :userInput';
        System.debug('Safe query: ' + query);
        return Database.query(query); // Safe using bind variables
    }

  2. Limit User Input: Validate and sanitize user input to ensure that it adheres to the expected format. For example, if you're expecting a numeric ID, verify that the input is a valid number.

  3. Avoid Dynamic SOQL when Possible: Whenever possible, avoid using dynamic SOQL (Database.query()) with user input. Instead, use static queries with bind variables.

 

Conclusion

In Salesforce development, security is paramount, and protecting against SOQL injection is an essential part of writing secure Apex code. By using the String.escapeSingleQuotes() method, you can escape user input and mitigate the risk of SQL injection attacks. However, for even greater security, it’s recommended to use bind variables and static queries whenever possible.

In this blog, we saw the difference between unsafe and safe methods for handling user input in SOQL queries and learned how to run the provided code to test these concepts. By following these best practices, you can help ensure that your Salesforce applications remain secure and resistant to malicious attacks.

  • Connect with us

  • sales@phenoble.com

  • hr@phenoble.com

  • +91 7850952954


© 2025 Phenoble Software Private Limited