この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

SOQL インジェクション

動的 SOQL クエリに渡されるユーザー制御データをサニタイズします。
SOQL または SOSL インジェクションは、入力されたユーザー制御データが Apex コードで適切にサニタイズされずに動的 SOQL または SOQL クエリに挿入されると発生します。次の 2 つのシナリオを考えます。
  • クエリの全体的な構造の変更
  • クエリパラメーターの値の変更

コール元が権限のないデータにアクセスできないようにする Apex コードを呼び出して、これらのシナリオを制御します。

次のコードを考えます。
1@AuraEnabled
2public static List<Account> getAccountName(string userId) {
3  if (FeatureManagement.checkPermission('readAccount')) {
4      string query='SELECT Name FROM Account WHERE Id=\''+ userId + '\'';
5      return database.query(query);
6  }
7}

ユーザーはクエリを制御して、権限を超える情報にアクセスできる可能性があります。

ユーザーがアクセスできる情報は、クエリの戻り値で制限されません。ユーザーは次のような文字列を送信できます。
1userId = '0035Y00003pPJiNQAW\' OR AnnualRevenue>100000.00 OR Name=\'a'
2// 0035Y00003pPJiNQAW is any id to any object that is not an account
クエリの戻り値として年間売上が $100,000 を超えるすべての取引先が返されます。これは、開発者が意図したコール元に返される内容ではありません。
SOQL または SOSL インジェクションを修正するには、コンテキストに応じた適切なエンコードが必要になります。String.escapeSingleQuotes をすべてのユーザー入力に適用するのではなく、SOQL または SOSL クエリのどこにあるのかに基づいて項目をサニタイズします。
  • WHERE (SOQL)、ORDER BY (SOQL)、WITH (SOSL)、FIND (SOSL) 句の変数の場合、束縛変数を使用します。
    1string query='SELECT Name FROM Account WHERE Id=:userId';
  • 項目名やテーブル名の場合、項目の describeResultisAccessible をコールします。また、宣言型ポリシーを適用するには、独自の手続き型ロジックを使用して、項目名やテーブル名をセキュリティポリシーで許可されている名前に制限します。
  • 引用符で囲まれた文字列のパラメーターの場合、バインド変数を使用します。バインド変数または String.escapeSingleQuote を使用して、引用符で囲まれたコンテキストにないテーブル名、項目名、パラメーターをサニタイズしないでください。
  • 他のプリミティブ型の場合、ユーザー入力をブール型、整数、ID、または他のプリミティブ (非文字列) 型にキャストします。
WITH SECURITY_ENFORCED キーワードでは SELECT および FROM 句のみがサニタイズされ、WHERE 句はサニタイズされないため、このキーワードは SOQL または SOSL インジェクション攻撃のサニタイザーにはなりません。