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

データベースクエリ構造が安全でないことが原因の SOQL インジェクション

Salesforce Object Query Language (SOQL) インジェクションを防ぐには、バインド変数と入力サニタイズを使用します。

SOQL インジェクションは、SOQL データベースクエリの一部がユーザによって直接制御される脆弱性です。Apex で実行される SOQL クエリは、ユーザ権限を順守しません。したがって、SOQL インジェクションを使用すると、ユーザの権限を昇格して、ユーザが自分の権限を越えるデータにアクセスできるようになります。

2 つのタイプの SOQL インジェクション脆弱性では、異なる保護のアプローチが必要です。

1 つ目のタイプでは、ユーザがクエリで不適切なテーブル名または項目名を指定します。ユーザデータで項目名またはテーブル名が識別されたら、指定されたテーブルまたは項目へのアクセス権限がユーザにあることを確認する必要があります。このタイプは、引用符で囲まれたコンテキストでないことに注意してください。

2 つ目のタイプでは、ユーザが引用符で囲まれた WHERE 句の一部を指定します。引用符で囲まれた文字列コンテキストにユーザデータが挿入されると、データは、引用符で囲まれたコンテキストの外に出ることがあります。保護のアプローチとして、バインド変数を使用することをお勧めします。EscapeSingleQuotes() を使用することもできます。どちらのアプローチでも、引用符で囲まれたコンテキストの外にユーザデータが出ることが防止されます。

SOQL クエリの項目名、テーブル名、WHERE 句の入力以外の部分をユーザに入力させてはなりません。

ユーザが生成したクエリを Apex で実行することは避けてください。この場合、クエリはシステムモードで実行されます。より複雑なクライアント側 SOQL を生成する必要がある場合は、REST または SOAP API を使用します。これにより、SOQL コールが安全に実行されます。

SOQL インジェクション、およびコードで SOQL インジェクションを防ぐ方法についての詳細は、Trailhead の「Secure Server-Side Development (セキュアなサーバーサイド開発)」を確認してください。

SOQL の例

次の SOQL ステートメントは、文字列と組み込みユーザ入力を連結して作成しているため安全ではありません。database.query ステートメントが実行される前に入力サニタイズは実行されません。
1string objType = id.valueOf(deduped[0].recordId).getSObjectType().getDescribe().getName();
2string soql = 'select id, ' + string.join(fields, ', ') + ' from ' +    objType +' where id in: lrIDs';
3list<sobject> records = database.query(soql);
動的 SOQL を使用する必要がある場合、EscapeSingleQuotes() メソッドを使用して、ユーザ指定の入力をサニタイズします。このメソッドは、ユーザ指定の文字列にあるすべての単一引用符にエスケープ文字 (\) を追加します。エスケープ文字を追加すると、すべての単一引用符が、データベースコマンドではなく、囲まれた文字列として処理されます。
1string objType = escapeSingleQuotes(id.valueOf(deduped[0].recordId).getSObjectType().getDescribe().getName());
2string soql = 'select id, ' + string.join(fields, ', ') + ' from ' +    objType +' where id in: lrIDs';
3list<sobject> records = database.query(soql);