この記事は新社会人のSalesforce学習記録とその他 Advent Calendar 2025の4日目の記事です。
SOQLは奥が深いので、2日に分けました。
安全に使用するために
世の中には〈b〉SOQLインジェクション〈/b〉とかいう攻撃があるそうで。
文字入力欄にSOQLの実行文を仕込み、実行する手法だそうです。
この攻撃に対して、Salesforceでは以下3つ
・escapeSingleQuotes()
・静的SOQL
・バインド変数
の対策方法があるみたいです。それぞれ見ていきます。
escapeSingleQuotes()
これは主に動的SOQLに対して有効です。
動的SOQLは主にSOQL文の中を動的に変えることができるタイプのものになります。
public class AdventCalendar {
public static void studyQuery(){
String matchedName='Taro';
String queryField='SELECT Id,Name FROM Account WHERE Name=\''+matchedName+'\'';
List<Account> acc=Database.query(queryField);
}
}
こんな感じで、StringでSOQLが指定されています。その後そのString文をDatabase.queryで指定するのが動的SOQLです。
見ての通り、この文には問題があります。現在の最終的なSOQL文は
SELECT Id,Name FROM Account WHERE Name='Taro'
となります。しかし、matchedNameがもし
String matchedName='X\' OR Name != \'';
とすると
SELECT Id,Name FROM Account WHERE Name='X' OR Name != ''
といった結果になります。matchedNameで元のSOQL文の条件部分が変更可能になります。

これが、escapeSingleQuotes()を使うだけで対策できます。
String matchedName='X\' OR Name != \'';
String queryField='SELECT Id,Name FROM Account WHERE Name=\''+string.escapeSingleQuotes(matchedName)+'\'';
System.debug(queryField);
結果は、

バックスラッシュが追加されることで、意図しないSOQL文への攻撃を防げます。簡単で便利です。
静的SOQL
主に[]で囲まれているタイプのSOQL文になります。
動的との違いとして、構造を変更できません。一般的によく使われるタイプのものになります。
List<Account> acc=[SELECT Id,Name FROM Account WHERE Name='Taro'];
こんな感じで取得することができます。構造が変わらないので、間違ってSOQL文を変えてしまうことがないのは安全です。
バインド変数
静的SOQLと一緒に使われているもので、変数が使いたいときはこれを使います。静的SOQLは
String matchedName='Taro';
List<Account> acc=[SELECT Id,Name FROM Account WHERE Name=:matchedName];
こんな感じで変数名の前に:をつけるだけです。たったこれだけで自動的に安全になります。簡単です。
まとめ
安全にSOQLを使用するために
動的SOQLは
→escapeSingleQuotes()を使う。
静的SOQLは
→バインド変数を一緒に使う。