静的解析とは?
静的解析とは、アプリケーションを実行することなく、ソースコードを自動で解析することです。
プログラムの実行中に解析が行われる場合、それは動的解析として知られています。
静的解析は、検出のためによく使われます。
- セキュリティの脆弱性。
- パフォーマンスの問題。
- 基準への不適合。
- 時代遅れのプログラム構造を使用している。
静的解析ツールはどのように機能するのですか?
すべての静的解析ツールに共通する基本的なコンセプトは、ソースコードを検索して、ある種の警告や情報が関連付けられた特定のコーディングパターンを特定することです。
これは、「JUnit 5のテストクラスは、"public "である必要はない」というような単純なものかもしれません。あるいは、「信頼されていない文字列入力がSQL実行文で使用されている」というような複雑な特定も可能です。
静的解析ツールは、この機能をどのように実装するかが異なります。
- ソースコードの解析技術で、抽象構文木(AST)を作成します。
- テキストの正規表現のマッチングを行います。
- 上記の組み合わせです。
テキストに対する正規表現のマッチングは、非常に柔軟性が高く、マッチングするためのルールを簡単に書くことができますが、多くの誤検出が発生したり、マッチングルールが周囲のコードのコンテキストを無視していたりすることがあります。
ASTマッチングでは、ソースコードを単なるテキストファイルではなく、プログラムコードとして扱います。これにより、より具体的で文脈に沿ったマッチングが可能となり、コードに対して報告される誤検出の数を減らすことができます。
継続的インテグレーションにおける静的解析
静的解析は、継続的インテグレーション(CI)プロセスの中で実行されることが多く、コンプライアンス問題のレポートを作成し、時間の経過とともにコードベースの客観的な見解を得るためにレビューすることができます。
コードの特定の部分のみを測定し、ルールのサブセットのみをレポートするように静的解析ツールを設定することで、コードの品質を客観的に測るために静的解析を利用する人もいます。
使用されるルールは、コードの評価に時間の経過とともに変化することがないため、客観性が保たれます。もちろん、使用するルールの組み合わせとその構成は主観的な決定であり、チームによって異なるルールを使用する場合もあります。
CIで静的解析を行うことは便利ですが、プログラマへのフィードバックが遅れる可能性があります。プログラマーはコーディング時にはフィードバックを受け取りませんが、後からコードを静的解析ツールで実行したときにフィードバックを受け取ります。CIで静的解析を行うことのもう一つの副作用は、結果が無視されやすくなることです。
チームが静的解析の結果にもっと注意を払うようにするには、通常、ビルドプロセスでしきい値メトリックを設定し、メトリックを超えた場合(例えば、いくつかのルールがトリガーされた場合)にビルドを失敗させることができます。
IDEでの静的解析
より早くフィードバックを得るために、要求に応じて、またはコードの変更に応じて定期的に、IDEで静的解析ルールを実行するIDEプラグインが数多くあります。
ルール違反は、プログラマーがコードを書いているときにIDE上で確認することができます。また、ルールを無視しにくくするために、違反箇所がエディタ上で下線付きのコードとして表示されるように設定することもできます。
個人的には、コーディングを改善するのに便利な方法だと思っています。特に、静的解析ツールでカバーされている新しいライブラリを扱うときには、この方法が有効です。ただし、誤検出や興味のないルールなど、「うるさい」こともあります。しかしこれは、特定のルールを無視するように静的解析ツールを設定するという余分なステップを踏むことで解決します。
静的解析ルールに基づいてコードを修正する
ほとんどの静的解析ツールでは、ルールの修正はプログラマーに任されているので、ルール違反の原因を理解し、どのように修正するかを考えなければなりません。
静的解析ツールの中には、違反を修正する機能を備えているものはほとんどありません。なぜなら、修正は、チームや使用している技術、合意しているコーディングスタイルに応じて行われることが多いからです。
デフォルトルール
静的解析ツールにデフォルトのルールが付属していると、プログラマが遭遇する可能性のあるすべての問題と、ルールが適用されるべきすべての状況をカバーしていると信じたくなるため、ルールの品質に対する誤った自信が生じることがあります。ルールが適用されるべき状況は微妙で、簡単には検出できない場合があります。
静的解析ツールを使用し、ルールや違反をより詳細に調査することで、プログラマーが自分の特定のドメインの文脈で問題を検出し、回避するスキルを身につけることを期待しています。
ドメインがコンテキストルールを必要とする場合、静的解析ツールにはドメインやライブラリにマッチするルールがないことがあり、さらにツールの設定や拡張が困難なことがよくあります。
アノニマス
これらの「煩わしさ」はどれも乗り越えられないものではありません。
- 偽陽性
- 修正不足
- ルールを無視する設定
- コンテキスト固有のルールの追加
しかし、これらは、そもそも静的解析ツールの使用を避けるための言い訳として使われることが多く、残念なことに、静的解析の使用は、その方法として非常に有用である。
- 若手開発者へのアプローチを強化
- 明確なコーディング違反に対する迅速なフィードバック
- プログラマーがこれまでに遭遇したことのないような不明瞭な問題を特定する。
- プログラマーが優れたコーディングアプローチを採用していることを補強する(違反が報告されない場合)。
IDEベースの静的解析ツール
プロジェクトの個人的な貢献者として、私は自分のコードに対する迅速なフィードバックを得るために、IDE内で実行される静的解析ツールを使いたいと思っています。
これは、プロジェクトが持つプルリクエストのレビュープロセスやCIの統合を補完するものです。
私は、自分の強みとなるツールを見つけ出し、個々のワークフローを改善するようにしています。
IDEで動作するツールは、基本的なGUIや設定方法が同じであるため、互換性があると考えてしまいがちです。
ツールの機能やルールセットは重複していることもありますが、最大限の効果を得るために、複数のツールをインストールしてそれぞれの強みを活かしています。
私がコーディングの際に積極的に使用している静的解析用のIDEツールは以下の通りです。
- 内蔵されたIntelliJ Inspections - 一般的なコーディングパターン
- SpotBugs - 一般的なエラー
- SonarLint - 一般的な使用パターン
- CheckStyle - よくあるスタイルパターン
- Sensei fromSecure Code Warrior - カスタムルールの作成
私がこれらを使用しているのは、それぞれがお互いを補強し、補うためにうまく機能しているからです。
IntelliJ Inspections
IntelliJをお使いの方は、すでにIntelliJのインスペクションをお使いだと思います。
これらは、IDEでフラグが立てられた静的解析ルールです。その中には、問題に対処するためにコードを書き換えるQuickFixオプションもあります。
ルールはオン・オフの設定が可能で、使用するエラーレベルを選択すると、IDEでハイライト表示されます。
良いIntelliJ Inspectionsはたくさんあります。これを書きながら、それらに目を通したからです。私はIntelliJ Inspectionsをデフォルトで使用しており、それらを設定していませんが、Inspectionsから最大限の価値を得るためには、それらに目を通し、自分のコーディングスタイルに関連するものを特定し、コード内でそれらに気づくように警告レベルを設定する必要があります。
IntelliJ Inspectionsの素晴らしい点は、IDEに無料で付属しており、マッスルメモリーを構築するのに役立つということです。
- コードを書くときにソースの警告やエラーに気づくことができる
- フラグのついたコードにマウスを合わせると、ルール違反を知ることができます。
- alt+enterで問題のQuickFixを適用する。
SpotBugs
SpotBugsIntelliJプラグインは、スタティック解析を使用して、コードのバグを警告します。
SpotBugsはIntelliJ Preferencesからコードをスキャンするように設定でき、実際に使用されるルールはDetectorタブで確認できます。
私は、コードを書いてレビューした後にSpotBugsを使うことが多いのですが、その際には「Analyze Project Files Including Test Sources」を実行します。
これは、バグや死んだコード、明らかな最適化などを特定するのに役立ちます。また、何をすべきかを判断するために、指摘された違反行為について調べざるを得ないこともあります。
SpotBugsは問題を発見しますが、問題解決のためのQuickFixアクションは提供しません。
SpotBugsは設定が簡単で、私のIDEで参考になる客観的なセカンドオピニオンとして重宝しています。
ソナーリント
SonarLintプラグインです。
SonarLintはIntelliJ Preferencesから設定することができ、コードを検証するルールを選択することができます。
デフォルトでは、SonarLintはリアルタイムで実行され、編集中のコードの問題を表示します。
SonarLintは迅速な解決策を提供するものではありませんが、違反レポートに関連する文書は通常、明確であり、十分な文書化がなされています。
これまでもSonarLintは、新しいバージョンのJavaの機能を知らせてくれる便利な存在でした。
チェックスタイル
CheckStyleプラグインでは、フォーマットとコード品質のルールを組み合わせて提供しています。
CheckStyleプラグインには、「Sun Checks」と「Google Checks」が同梱されています。
これらの定義は、インターネットで簡単に調べることができます。
CheckStyleが最も価値を発揮するのは、プロジェクトが時間をかけて独自のルールセットを作成したときだ。そして、IDEプラグインがそのルールセットを使用するように設定し、プログラマはコードをCIにコミットする前にスキャンを実行することができる。
CheckStyleは、CIプロセスにおいて、CheckStyle違反の数が閾値を超えた場合に、ビルド失敗のプラグインとして使用されることが非常に多い。
Sensei
Senseiは、AST(Abstract Syntax Tree)をベースにした静的解析を用いてコードを照合し、QuickFixを作成します。
例えば、新しいクラスをコードに追加した場合、そのクラスのインポートはソースファイルに一度だけ追加され、置換ごとに追加されることはありません。
Sensei は、他のツールでは存在しない、あるいは設定が難しいカスタムマッチングルールを簡単に構築するために作られました。
設定ファイルを修正するのではなく、すべての設定をGUIで行うことができます。新しいレシピを作成する際には、そのレシピがどのコードにマッチするかをGUIで簡単に確認することができます。また、QuickFixを定義する際には、コードの修正前と修正後の状態をすぐに比較することができます。これにより、チームや技術、さらには個々のプログラマーに固有のレシピなど、非常に文脈に沿ったレシピを簡単に作成することができます。
私はSensei を他の静的解析ツールと組み合わせて使用しています。例えば、ほとんどの静的解析ツールは問題を発見しますが、修正することはできません。Sensei の一般的な使用例は、他のツールの一致する検索をSensei で再現し、クイックフィックスでそれを拡張することです。これには、適用されるカスタム修正が、プロジェクトのコーディング標準をすでに満たしているという利点があります。
私は定期的に、Intensionレポートが私が作成したコンテキストに全くマッチしていなかったり、IntelliJが提供するQuickFixが私が使用したいコードパターンにマッチしていなかったりするために、IntelliJ Intensionsセットに既に存在するSensei レシピを作成することがあります。
私は既存のツールを完全に置き換えようとするのではなく、既存のツールを補強します。
Sensei は、一般的なルールの文脈上のバリエーションを特定する場合にも非常に便利です。例えば、静的解析ツールでサポートされていないSQLライブラリを使用しているが、静的解析エンジンの一般的なSQLルールがまだ適用される場合、Sensei を使用して、これらのルールのライブラリ固有のバリエーションを作成することができます。
Sensei は、前述の静的解析ツールのように多くの一般的なレシピが用意されているわけではなく、特定のコーディングスタイルやユースケースに合わせて設定されたQuickFixを備えた新しいレシピを簡単に作成できることが強みです。
注:一般的な使用例をカバーするレシピの公開を目指しています。 ここで見つけることができます。.
概要
私は、一緒に機能し、設定が可能で、自分の特定の状況に合わせて簡単に拡張できるツールを選ぶ傾向があります。問題を特定したり、使用しているプログラミング言語やライブラリについて詳しく知るために、IDEの静的解析ツールを何年も使用してきました。
私は前述のツールをすべて組み合わせて使っています。
- IntelliJ Intentionsは、一般的なコードの問題にフラグを立て、しばしば関連するQuickFixを提供します。
- SpotBugsは、私が見落としていたかもしれない簡単なバグを見つけ、パフォーマンスの問題を知らせてくれます。
- SonarLintは、私が気づいていなかったJavaの機能を特定し、コードをモデリングするための新たな方法を提案してくれます。
- CheckStyleは、CIの際にも強制される、合意されたコーディングスタイルに適合させるのに役立ちます。
- Sensei は、静的解析ツールで見つかった一般的なシナリオを補強するQuickFixの作成や、他のツールでは設定が難しい特定のプロジェクトや技術のレシピの作成に役立ちます。
---
IntelliJの「Preferences ŌPlugins」(Mac)または「Settings ŌPlugins」(Windows)から、「sensei secure code」を検索して、「Sensei 」をインストールします。
Secure Code Warrior GitHub アカウントの `sensei-blog-examples` プロジェクトには、一般的な使用例を示すサンプルコードやレシピが格納されています。
https://github.com/securecodewarrior/sensei-blog-examples
についてはこちらをご覧ください。Sensei