Intermediate 30 min read

Dynamic SOQL and Injection Risk

By the end of this lesson, you'll be able to:

  • Build a query as a String and execute it with Database.query()
  • Explain what SOQL injection is and how it happens
  • Use String.escapeSingleQuotes() to defend against it when bind variables aren't possible

Prerequisites: "Bind Variables"

Building and running a dynamic query

String fieldName = 'Industry';
String queryString = 'SELECT Id, Name FROM Account WHERE ' + fieldName + ' = \'Technology\'';

List<Account> accounts = Database.query(queryString);

Database.query(someString) executes a query built as a String at runtime — necessary when even the field being filtered on isn't known until the code runs, which a fixed inline query (every example so far) can't express.

What SOQL injection looks like

// DANGEROUS: directly concatenating raw user input into query text
String userInput = "'; DELETE Account WHERE Id != '000000000000000AAA"; // a malicious example
String queryString = 'SELECT Id FROM Account WHERE Name = \'' + userInput + '\'';

If userInput comes directly from a form field and gets concatenated straight into the query text unescaped, a carefully crafted input could alter the query's actual structure — this is SOQL injection, the same category of vulnerability as SQL injection in traditional web applications.

The defense: bind variables first, escaping second

// BEST: bind variables work in dynamic SOQL too
String targetName = userSuppliedName;
List<Account> accounts = Database.query('SELECT Id FROM Account WHERE Name = :targetName');

// If you truly must concatenate raw text, escape it first
String safeInput = String.escapeSingleQuotes(userSuppliedName);
String queryString = 'SELECT Id FROM Account WHERE Name = \'' + safeInput + '\'';

Bind variables (previous lesson) work inside dynamic SOQL strings too — this is the preferred defense whenever possible, since it never concatenates raw text into the query. When a value truly must be concatenated directly (rare), String.escapeSingleQuotes() neutralizes quote characters that could otherwise break out of the intended query structure.

Exercise

As a comment, explain why concatenating raw user input directly into a dynamic SOQL string is dangerous, and name the safer alternative.

Show hint

Think about what a malicious input could do to the query's structure.

APEX

Dynamic SOQL and Injection Risk Quiz

1. What is SOQL injection?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Dynamic SOQL builds a query as a String at runtime for cases a fixed query can't handle — but building that String carelessly from user input opens the door to SOQL injection.