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