One of the most important features of an application is the ability to store and retrieve data from the underlying database layer. This interaction with the database happens through SQL in traditional web applications and through SOQL in the Salesforce application. SOQL in Salesforce is a prime target for exploitation for an attacker trying to gain access to the org’s data.
When a developer trusts a user input incorrectly, leading to exposure of information which is referred to as SOQL Injection attack. With Salesforce development involving database interactions, risk of SOQL injection is obvious
Let’s go through an example demonstrating how a SOQL attack can happen
Below is a VF Page and Apex Controller code which is used to demonstrate this. We’ve developed a custom page that enables users to search through their contacts. This list is filterable by providing a title filter in the search box.
Now type in a title filter like VP. The page acts as expected and returns the filtered contacts. The application takes a parameter(textual title) entered by the user and places it directly into the SOQL query.
This might lead to SOQL injection! As SOQL injection occurs when an attacker modifies the structure of the query. So, let’s try a more complex filter and see what the actual result is.
Try entering the following filter in the title search to have the database identify contacts: %’ and a name like ‘%
This filter enables the attacker to close the single quote for the title and add another filter for name thus gaining them access to the data which was secure.
In order to build secure apps that are not vulnerable to SOQL injection, the developer can use some techniques explained below to avoid such attacks.
Use Static Query and Bind Variables:
Using static query and Bind variables mitigates the risk posed by directly using user input in your dynamic SOQL.
This ensures that the user-controlled input is considered as a variable and not as an executable part of the query.
For example, if we add the filter test’ LIMIT 1 in a static query for contacts, it looks for contacts with titles that are “test’ LIMIT 1”. With a bind variable, the attacker can’t break out and control the SOQL salesforce query.
Escaping Single Quotes:
Another mitigation option that is used by developers who use user input in their queries is the escape function string.escapeSingleQuotes(). This function escapes any instance that it finds of a ‘ quote in the string using the backslash (\) escape character.
This prevents an attacker’s input from being treated as code by constraining them to the boundary of the string. If in the above apex class we add string.escapeSingleQuotes() around the variable textual title and then try the filter as %’ and a name like’%. The SOQL injection payload will no longer function!. Some other useful techniques are Typecasting, Replacing characters and Whitelisting