フロー解析エンジンは、解析されたコードからパスを分析し、さまざまな問題を検出します。アプリケーション全体にわたって「実行される可能性があるパス」をすべて解析するのは現実的ではない場合もあるため、解析レベルの深さを設定できます。解析レベルが深いほど、発見される違反の数が増えます。ただし、パフォーマンスが低下し、若干メモリの消費量が増加します。
解析の深さは、DTP でテスト コンフィギュレーション インターフェイスを使用して設定します。 Report Center > [テスト コンフィギュレーション] > [静的解析] > [フロー解析詳細設定] > [パフォーマンス] > [解析の深さ] にアクセスし、以下のいずれかのオプションを選択します。
デフォルトの解析レベルの深さは [標準] です。
解析レベルの深さの他に、フロー解析エンジンはタイムアウト設定を利用して、妥当な時間内で解析が終了するようにします。タイムアウトの設定を行うには、DTP でテスト コンフィギュレーション インターフェイスを使用します。Report Center > [テスト コンフィギュレーション] > [静的解析] > [フロー解析詳細設定] > [パフォーマンス] > [タイムアウトの方針] にアクセスし、以下のいずれかのオプションを選択します。
デフォルトのタイムアウト オプションは [時間] であり、タイムアウト秒数は 60 秒です。解析中に発生したフロー解析タイムアウトについての情報を得るには、解析後に生成されるレポートで [セットアップの問題] セクションを確認してください。
スワップ モードでは、解析データをハードディスクに書き込みます。解析データのスワップは、インクリメンタル解析と同じ永続性記憶装置を使用し、インクリメンタル解析と似たプロセスで実行されます。大きなプロジェクトで解析を実行する場合、解析するソース コードの意味論的モデルを表す解析データが、フロー解析が使用できるすべてのメモリを消費する可能性があります。この現象が発生した場合、フロー解析は現在必要ない解析データをメモリから削除し、後でディスクから再び読み込みます。
一般的に、 Xmx JVM オプションを使って JVM ヒープのサイズを大きくしてJtestを実行することを推奨します。これはスワップを最小限にするためであり、結果としてパフォーマンスが向上します。充分なメモリがある場合、解析データのスワップは無効化しても構いません。スワップを無効化すると、コード解析の速度が上がる場合があります。
スワップ モードを有効化/無効化するには、DTP のテスト コンフィギュレーション画面を使用します。
ディスクへの解析データのスワップを有効化: デフォルトで 有効 です。大量のメモリを必要としない小さなサイズのプロジェクトに対してフロー解析を実行する場合、または 64-bit システムのように十分なメモリがある場合、このオプションを無効化すると、解析のパフォーマンスが向上する場合があります。
DTP のテスト コンフィギュレーション画面では、次のオプションを設定できます。
[null チェック メソッド] オプションを指定すると、メソッドに null パラメーターが渡されたときに返す期待値を指定できます。そのため、偽陽性が減少するほか、null 変数の値が不明なときに通常作成される過剰なパスが減少します。
[有効] チェックボックスをオンにして、以下の情報を指定します。
フロー解析は解析スコープでメソッドを解析します。たとえばサード パーティのライブラリなど、現在の解析スコープの外にメソッドがある場合、null チェック メソッドでパラメーターを指定する必要があります。この例のクラスは、異なるアセンブリに定義されており、解析スコープ (UString
) の外にあります。このクラスには、Java の文字列があるコードをさまざまな方法で操作するための static メソッドがあります。その 1 つが UString.isEmptyOrNull(String)
であり、これは以下のように定義されます。
public class UString { static boolean isEmptyOrNull(String variable) { if ((variable == null) || (variable.length() == 0)) { return true; } return false; } } |
そして、フロー解析の ルール BD-EXCEPT-NP ルールによって解析される次のクラスがあります。
public class SomeClass { void someMethod(String variable) { boolean flag = variable == null; // violation search starts here if (UString.isEmptyOrNull(variable)) { /** * In case variable is null, we will always get to this branch of the if clause. */ System.out.println("String is empty"); } else { variable.toString(); // FALSE POSITIVE BD-EXCEPT-NP VIOLATION } } } |
フロー解析は メソッド isEmptyOrNull()
の戻り値が不明であると仮定します。その理由は、このメソッドは解析スコープ中にないからです。フロー解析は if
文の then
および else
ブランチを解析し、それらの文の 1 つで違反を発見します。しかし、変数が null の場合、このメソッド呼び出しは true を返します。
null チェック メソッドのメソッド リストに UString.isEmptyOrNull()
を追加して戻り値を指定することで、追跡された変数がこのメソッドに渡されたときにフロー解析は違反をレポートしなくなります。なぜなら、if
文の誤ったブランチが解析されず、その結果として偽陽性が回避されるからです。
null チェック メソッドのパラメーターに追加されるメソッドは、単純な Boolean 型の戻り値を持つ、static メソッドであるべきです。この制限事項は、パラメーター指定が複雑になり過ぎることを防ぎ、null チェック メソッドの結果に影響しかねない変数が他にないことを保証します。
[リソース] タブでは、BD.RES (リソース) カテゴリのルールを使ってチェックするリソースを定義することができます。BD.RES カテゴリのルールは、[リソース] タブで定義および有効化されているすべてのリソースについて、リソースが正しく使用されているかをチェックします。
矢印をクリックして [リソース アロケーター] および [リソース クローザー] タブを開き、表示されたテーブルにリソースのアロケーター/クローザーの情報を入力します。詳細については以下のセクションを参照してください。
[リソース アロケーター ] テーブルには、リソースを生成するメソッドの記述を入力できます。テーブルには以下の列があります。
一般的に、アロケーター メソッドはエラー コードを返してリソース割り当ての失敗を表します。アロケーターメソッドはリソースを返し、通常 NULL 値はリソース割り当ての失敗を表します。リソース リークを探すときに、フロー解析はリソースの割り当てが成功したか失敗したかを把握できる必要があります。これは、割り当てが実際に発生したパス上で発見されない割り当て解除メソッドへの呼び出しだけをフロー解析がレポートするのに役立ちます。リソース アロケーターメソッドがリソースを返し、NULL でない場合、フロー解析はリソースが正常に割り当てられたと推測します。
[リソース クローザー] テーブルには、リソースをクローズするメソッドの記述を入力できます。テーブルには以下の列があります。
[常に解析すべきメソッド] オプションを使用すると、実行パス中で見つかったとき常に解析するメソッドを定義できます。これにより、特定のパスを解析したとき、通常は入らないメソッドを必ず解析するようにできます。
[有効] チェックボックスをオンにし、テーブルに以下の情報を入力します。
[メソッド パラメーターを汚染する Spring HTTP リクエストのアノテーション] オプションを使用すると、メソッドの 1 つまたはそれ以上のパラメーターを汚染する Spring アノテーションを指定できます。このオプションは、[汚染データのソース] パラメーターがあり、 Spring HTTP リクエストからのデータを汚染されているとして扱うよう設定された BD.SECURITY カテゴリのルールにだけ適用されます。
アノテーションを設定するには、次の表のいずれかの操作を行います。
テーブルには以下の列があります。
[インジェクション アノテーション] オプションを使用すると、インジェクションに使用するアノテーションを定義できます。このオプションを指定すると、フィールド またはセッター メソッドにアノテーションがある場合、フロー解析はそのフィールド値は未初期化または null の可能性がないとみなします。
テーブルには以下の列があります。
Spring フレームワークを使用するプロジェクトを解析するのに特別な設定は必要ありません。 フロー解析は、Spring フレームワークの特徴を自動的に認識し、レポートされた違反を調整して正確な結果を表示します。
以下のセクションでは、フロー解析による Spring フレームワークの処理の詳細と、フロー解析ルールのレポートする違反への影響について説明します。
フロー解析は、Spring インジェクションに使用されるアノテーションを識別します。アノテーションが付けられたフィールドは自動的に初期化されます。フィールド にアノテーションがある場合、フロー解析はそのフィールド値は未初期化または null の可能性がないとみなします。これにより、以下のルールが違反を誤検出するのを防ぎます。
フィールドを自動的に初期化するインジェクション アノテーションのデフォルトのリストを参照したり、テスト コンフィギュレーションを編集することでリストをカスタマイズできます ([静的解析の設定] > [制御フレームワークの置換の設定])。
フロー解析は、Spring コントローラー クラスおよび HTTP リクエスト処理メソッドが使用されているかを識別できます。結果として、以下のことが可能です。
フロー解析は、Java Validation API は汚染されたデータの適切な検証を確実に行うには十分でないと見なします。Java Validation は、多くの場合、外部ソースから取得したデータを検証するのに使用されますが、汚染されたデータは、特定のコンテキストで使用する前に適切にサニタイズされる必要があります。つまり、適切な検証を行うには、データが SQL クエリーに渡されるのか、HTTP レスポンスに埋め込まれるのかに応じて、異なる検証メソッドを使用する必要があるということです。
フロー解析は、Spring 特有の汚染された可能性があるデータのソースを認識できます。汚染されたデータを検出するフロー解析ルールは、以下のソースから取得したデータが検証せずに危険なメソッドに渡されている場合、違反をレポートします。
Spring HTTP リクエストが汚染されたデータのソースになると仮定するルールについては、メソッドの 1 つまたはそれ以上のパラメーターを汚染する Spring アノテーションを指定できます、詳細については「メソッド パラメーターを汚染する Spring アノテーションの指定」を参照してください。