概要
SOQLインジェクションは、SalesforceのApex言語で使用されるSOQL(Salesforce Object Query Language)クエリにおいて、ユーザーが提供する悪意のある文字列がデータベースクエリの一部として実行され、不正なデータアクセスやデータ変更を引き起こす攻撃です。この脆弱性は、ユーザー入力を適切に検証やサニタイズせずに動的SOQLクエリに組み込むことで生じます。
Apex での SOQL インジェクションの脆弱性
SOQLインジェクションは主に、ユーザーからの入力を検証せずに動的クエリに組み込むことで発生します。例えば以下のApexコードを見てみましょう。
public class SOQLController {
public String name { get; set; }
public PageReference query() {
// 危険: ユーザーの入力がエスケープされずにクエリに組み込まれている
String qryString = 'SELECT Id FROM Contact WHERE (IsDeleted = false and Name like \'%' + name + '%\')';
List<Contact> queryResult = Database.query(qryString);
System.debug('query result is ' + queryResult);
return null;
}
}
このコードはユーザーが提供するname
を使って取引先責任者の名前を検索しますが、SOQLインジェクションに対して脆弱です。
例えば、ユーザーがtest%') OR (Name LIKE '
という値をname
に入力した場合、結果のクエリは以下のようになり、すべての取引先責任者を返します。これは、悪意のあるユーザーがクエリのロジックを変更して、意図しないデータにアクセスすることを可能にする例です。
SELECT Id FROM Contact WHERE (IsDeleted = false AND Name LIKE '%test%') OR (Name LIKE '%')
SOQL インジェクションの防御策
- 1.変数バインディングを使用する
-
Apexにおいては、クエリ内で変数を直接利用することが可能です。これはSOQLインジェクションを防ぐ効果的な手法です。
String queryName = 'John Doe';
List<Contact> queryResult = [SELECT Id FROM Contact WHERE Name = :queryName];
上記のコード例において、:queryName
の部分が変数バインディングを使用しています。この :
プレフィックスは、Apex変数 queryName
の値をSOQLクエリに直接組み込むためのものです。この方法で変数の値をクエリに組み込むことで、動的に文字列を組み立てることなく、安全にクエリを実行することができます。
- 2.escapeSingleQuotes メソッドを使用する
-
このメソッドは、文字列内の単一引用符にエスケープシーケンスを追加し、文字列リテラルの一部として扱われるようにします。
String userInput = "O'Reilly";
String safeInput = String.escapeSingleQuotes(userInput);
これにより、ユーザーの入力を安全にクエリに組み込むことができます。
public class SOQLController {
public String name { get; set; }
public PageReference query() {
// ユーザー入力をエスケープして安全性を高める
String queryName = '%' + String.escapeSingleQuotes(name) + '%';
// 安全な変数バインディングを使用してクエリを実行
List<Contact> queryResult = [SELECT Id FROM Contact WHERE (IsDeleted = false and Name like :queryName)];
System.debug('query result is ' + queryResult);
return null;
}
}
防御策を適用すべきシチュエーション
- ユーザーの入力を基に動的SOQLクエリを構築する際: フォームや検索バーからの入力をクエリに組み込む際には、特に注意が必要です。
- レポートやダッシュボードのフィルタとしてユーザー入力を利用する際: Salesforceのレポートやダッシュボード機能にユーザーがフィルタ条件を入力する際にも、インジェクション攻撃のリスクがあります。
- システム外部からのデータを使用してクエリを実行する際: API経由や他のシステムからインポートされるデータは、信頼性が検証されていない可能性があるため、クエリに組み込む前に適切な検証が必要です。
- URLパラメータやフォームの入力から直接SOQLクエリを組み立てる際: WebアプリケーションでURLパラメータを利用してデータベースクエリを構築する場合にも、SOQLインジェクションの可能性があります。
- アプリケーション間の統合時: 他のアプリケーションやシステムからのデータを受け取る際は、受け取ったデータを信頼する前に適切にサニタイズすることが不可欠です。
まとめ
SOQLインジェクションは、Salesforce開発者が常に意識すべき重要なセキュリティリスクです。このリスクを効果的に管理するためには、安全なコーディング慣行を理解し、適切に実施することが不可欠です。上記の方法でユーザー入力を適切に処理することで、アプリケーションのセキュリティを強化し、不正なデータアクセスを防ぐことができます。
コメント