問題
SOQLインジェクションの脆弱性から保護するために、開発者がVisualforceコントローラで使用できるクエリはどれですか。2つ選びなさい。
A
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
B
String qryName = '%' + Name + '%';
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
C
String qryName = '%' + String.escapeSingleQuotes(name) + '%';
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
D
String qryName = '%' + String.enforceSecurityChecks(name) + '%';
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
正解
BとC
解説
それぞれの選択肢の理由について説明します。
A
これは不正解です。変数 qryName
をバインド変数として使用しているSOQLクエリを示しています。Apexでバインド変数を使用する場合、この変数は自動的にクォートされるため、通常、SOQLインジェクション攻撃に対して安全です。ただし、qryName
の値がどのように設定されているかが示されていないため、その安全性を完全に評価することはできません。この変数がユーザーの入力をサニタイズせずに直接受け取っている場合、インジェクションの脆弱性が生じる可能性があります。安全なコーディング慣行として、ユーザー入力を使用する前に、適切なエスケープまたは検証を行うべきです。
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
B
これは正解です。このクエリは、バインド変数を使用してユーザー入力をクエリに埋め込んでいます。Nameがユーザー入力であっても、バインド変数を使用することで、SOQLインジェクションのリスクは回避されます。静的クエリとバインド変数を使用することで、ユーザー入力が直接クエリに埋め込まれることはありません。
String qryName = '%' + Name + '%';
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
C
これは正解です。String.escapeSingleQuotes()メソッドは、文字列内のシングルクォートをエスケープするためのSalesforce提供のメソッドです。これにより、SOQLインジェクションのリスクを軽減することができます。
String qryName = '%' + String.escapeSingleQuotes(name) + '%';
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
D
これは不正解です。String.enforceSecurityChecks(name)
は、標準のSalesforceのメソッドではないため、ここではSOQLインジェクションに対する保護としては適切ではありません。また、String.enforceSecurityChecks
というメソッドはSalesforce Apexには存在しないため、このコードはコンパイルエラーを引き起こす可能性があります。
String qryName = '%' + String.enforceSecurityChecks(name) + '%';
String qryString = 'SELECT Id FROM Contact WHERE Name LIKE :qryName';
List<Contact> queryResults = Database.query(qryString);
コメント