Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
Salesforce Developer
hard

How do you prevent SOQL injection in Apex?

SOQL Injection is when user input gets concatenated into a SOQL query, allowing the user to manipulate the query structure. Like SQL injection but for Salesforce.

Vulnerable code:

apex public List<Account> findByIndustry(String userInput) { String query = 'SELECT Id, Name FROM Account WHERE Industry = \'' + userInput + '\''; return Database.query(query); }

If userInput is ' OR Name LIKE '% — the query becomes WHERE Industry = '' OR Name LIKE '%' — returns all accounts.

Safe patterns:

1. Bind variables (always preferred):

apex public List<Account> findByIndustry(String userInput) { return [SELECT Id, Name FROM Account WHERE Industry = :userInput]; }

Salesforce parameterises bind variables; injection is impossible.

2. Bind variables in dynamic SOQL:

apex String safeIndustry = userInput; // bound below String query = 'SELECT Id FROM Account WHERE Industry = :safeIndustry'; List<Account> accs = Database.query(query);

The : prefix in dynamic SOQL is parameterised the same way.

3. `String.escapeSingleQuotes` for cases where bind variables can't work:

apex String escaped = String.escapeSingleQuotes(userInput); String query = 'SELECT Id FROM Account WHERE Name LIKE \'%' + escaped + '%\'';

Escapes single quotes within the string. Less robust than bind variables; use only for legitimate cases like wildcard concatenation.

4. Whitelist for object/field names (which can't be bind-variable):

apex Set<String> allowedObjects = new Set<String>{'Account', 'Contact', 'Opportunity'}; if (!allowedObjects.contains(userInput)) throw new IllegalArgumentException(); String query = 'SELECT Id FROM ' + userInput;

5. `Schema.SObjectType.validate(input)` patterns — validate against the org's known objects and fields before composing queries.

Rules of thumb:

  • Never concatenate raw user input into a SOQL query string.
  • Bind variables for values; whitelist for identifiers (object/field names).
  • Don't trust client-side validation — validate again in Apex.
  • Audit `Database.query` and `Database.queryWithBinds` usages — these are the injection surfaces.

Beyond SOQL: similar principles apply to dynamic SOSL, dynamic DML, and dynamic Visualforce/LWC component instantiation. Anywhere user input meets a runtime parser, sanitisation matters.

Tooling: PMD has SOQL-injection detection rules. Run static analysis as part of CI.

Why this answer works

Senior security. The bind-variable rule, escapeSingleQuotes, and whitelist patterns together are comprehensive. Mentioning PMD signals tooling maturity.

Follow-ups to expect

Related dictionary terms