4.4

4.4 静的解析とコードの臭いの指標

概要と動機

静的解析のツールは、ソースコードを実行することなく走査し、欠陥、セキュリティの脆弱性、あるいは保守可能性の問題と相関することが知られているパターンに旗を立てます。到達不能なコード、閉じられていないリソース、疑わしい型の強制変換、重複したロジック、そしてより広いカテゴリーであるコードの臭い、必ずしもバグではないが、コードを理解、テスト、あるいは安全に変更するのを難しくする傾向のある構造的なパターンです。静的解析は、このパートの他のトピックにあるより的を絞った指標の下にある自動化された継続的な層であり、すべてのコミットで実行され、定期的な監査を待つのではなく、問題が導入された瞬間にそれを表面化させます。

本トピックの中心的な関心事は、静的解析のツールが報告するものと、実際に重要なものとの間の隙間です。あるツールは大規模なコードベースにわたって何千もの発見を旗立てすることができ、発見の件数だけでは乏しい指標です。なぜなら、それは些細なスタイルの好みを本物の深刻なリスクと混同しており、本物の修正を通じてと同じくらい容易に抑制を通じて減らすことができるからです。静的解析の価値は、素の発見件数からではなく、組織が重要度をどれだけうまくトリアージし、後退を防ぎ、ツールの判断を人間のレビューの補完としてではなく代替として扱う誘惑にどれだけ抵抗するかから来ます。

大規模なチームにとって、静的解析は、どんなチームも手動で完全にレビューできるよりも大きなコードベースにわたって、コードの品質とセキュリティの衛生のベースラインを強制する唯一の実践的な方法です。セキュアなコーディングの慣行についてのコンプライアンス要件に直面することが多い企業や政府の組織は、人間のレビュー担当者がたまたま問題に気づいたときだけではなく、ベースラインレベルの精査が一貫して適用されたことの文書化され監査可能な証拠として、静的解析に依存しています。

重要な原則

  • 素の発見件数はそれ自体では乏しい指標である。 それは些細な問題と深刻な問題を混同し、本物の修正ではなく抑制を通じて操作されうる。
  • 重要度のトリアージは量よりも重要である。 少数の重大な発見は、多数の些細な発見よりも多くの注意に値します。
  • 静的解析は人間のレビューを補完するのであり、それに取って代わるものではない。 ツールはパターンを捉えますが、意図やビジネスの文脈を理解しません。
  • 「新しく導入された問題」の傾向は、バックログの総件数よりも行動可能である。 それは現在の慣行が改善しているか後退しているかを教えてくれます。
  • 誤検知はツールへの信頼を蝕む。 管理されていない誤検知率は、チームが本物のものを含めて発見全体を無視することにつながります。

推奨事項

素の件数ではなく重要度で重みづけされた発見を追跡する

あなたの静的解析のツールを、発見を重要度(重大、高、中、低、あるいは同等の尺度)によって分類するよう設定し、平坦な合計件数ではなく重要度で重みづけされた傾向を追跡してください。重大な発見がゼロで500の低重要度のスタイルの提案があるコードベースは、重大な発見が50でスタイルの問題がまったくないコードベースとはまったく異なる状態にあり、素の件数はこれらが同等ではないのにおおよそ同等であるかのように扱います。

歴史的な総バックログではなく、新しく導入された発見でゲートをかける

ほとんどの確立されたコードベースは、現在の慣行より前から存在し、一度にすべて修正するには法外な費用がかかるであろう、発見の遺産のバックログを抱えています。バックログ全体がクリアされるまですべての仕事をブロックするのではなく、特定の変更が合意された重要度の閾値を超える新しい発見を導入するかどうかでCIをゲートし、さらなる蓄積を防ぎながら通常の保守を通じてバックログが段階的に縮小するようにしてください。この区別は、トピック4.2のカバレッジの下限についての推奨事項を反映しています。非現実的な一度きりの修正を要求するのではなく、後退から守るのです。

誤検知率を能動的に管理する

発見のサンプル、特に件数の多いカテゴリーのものを定期的にレビューし、そのうちどれだけが本物の誤検知、つまりツールが文脈上実際には問題ではないパターンに旗を立てたケースであるかを確認してください。チームが、あまりに多くがノイズであるという理由で、ツールの出力を全体として無視する習慣を発展させてしまうのではなく、ルールの設定を調整して、本物に騒がしく低価値のルールのカテゴリーを特に抑制してください。高く管理されていない誤検知率は、静的解析プログラムの信頼性を破壊する唯一最速の方法です。

静的解析の発見を自動的な判決としてではなくレビューのための合図として使う

本物の誤検知ではない正当な発見であっても、常に自動的で必須の修正を正当化するわけではありません。旗立てられたパターンの中には、ツールが見られない特定の文脈を考えれば許容できるものもあります。すべての発見を強制的に執行するのでも、ツールの価値を時間とともに蝕む静かで文書化されていない抑制を許すのでもなく、人間が発見をレビューし、それを修正するか、あるいは文書化された理由とともに明示的に目に見える形で免除するための軽量なプロセスを構築してください。

このパートの他のコード品質の指標と静的解析を組み合わせる

静的解析の発見、複雑さのスコア(トピック4.1)、そしてホットスポットのデータ(トピック4.3)は、競合する指標ではなく補完的な証拠です。未解決の静的解析の発見が高い濃度で集中しており、同時にチャーン複雑さのホットスポットでもあるファイルは、優先順位づけられた注意の特に強い候補です。なぜなら、複数の独立した信号が同じ結論に収束しているからです。

トレードオフ:長所と短所

アプローチ長所短所
指標としての素の発見件数報告が単純些細な問題と深刻な問題を混同する。抑制を通じて容易に操作される
重要度で重みづけされた傾向より正確に実際のリスクを反映する継続的な重要度分類の保守が必要
歴史的な総バックログでゲートをかける最終的なコードの清潔さを最大化する確立されたコードベースにはしばしば非現実的。すべての仕事を止めることがある
新しい発見だけでゲートをかける実践的で、後退を防ぎ、バックログを段階的に縮小させる意図的な是正計画なしでは遺産の問題がより長く持続する

中心にある緊張関係は徹底性と実践性です。新しい仕事が進む前に歴史的なバックログ全体を解決することを要求する静的解析の方針は徹底的ですが、本物の歴史を持つどんなコードベースにとっても通常非現実的であり、そのプレッシャーのもとにあるチームは本物に修正するのではなく発見を全体として抑制する傾向があります。この緊張を解消するには、新しい発見については厳格にゲートをかけながら、本トピックとトピック4.3が推奨する重要度と相互参照の技法を使って優先順位づけられた、遺産のバックログに対する別個の意図的にペース配分された是正の取り組みを実行してください。

チームで話し合うべき問い

  1. 私たちは重要度で重みづけされた傾向を追跡しているでしょうか。それとも単に素の合計発見件数でしょうか。 あなたの実際のダッシュボードを持ち出して確認してください。素の件数は多くのツールで既定ではよくあり、代わりに重要度を適切に表面化させるには意図的な設定がしばしば必要です。

  2. 私たちの現在の未解決の発見の遺産のバックログはどれだけ大きく、私たちはそれを減らす意図的でペース配分された計画を持っているでしょうか。それとも単に無期限に蓄積しているでしょうか。 対処されず静かに成長するバックログはよくあることであり、検証されないままにするのではなく正直に名指しする価値があります。

  3. 私たちの最も件数の多い発見のカテゴリーについて、私たちの推定誤検知率はどれだけで、私たちはそれに応じてルールの設定を調整したでしょうか。 もしこれを一度も確認したことがないなら、あなたの最も騒がしいカテゴリーから発見のバッチをサンプリングし、そのうちどれだけが本物に行動可能かを正直に評価してください。

  4. 私たちのチームのエンジニアは静的解析の発見を信頼しているでしょうか。それとも、出力のあまりに多くがノイズであるという理由で、それを無視することを学んだでしょうか。 これは、チームに尋ねる価値のある直接的で正直な実態確認の問いです。なぜなら、無視されるツールは、その理論的な能力にかかわらず本物の価値を提供しないからです。

  5. 私たちは現在、特定の文脈を考えればチームが免除されるべきだと信じる正当な発見をどう扱っているでしょうか。 あなたのプロセスがこれを目に見える文書化された決定にしているか、それとも時間とともにツールの信号を蝕む静かで文書化されていない抑制を通じて起きているかを確認してください。

  6. 静的解析の発見、複雑さのスコア、ホットスポットのデータは、私たちのコードベースのどこで同じファイルやモジュールに収束しているでしょうか。 これら三つの信号を明示的に相互参照してください。複数の独立した指標にわたる収束は、どの一つだけよりも強い優先順位づけの信号です。

業種別の視点

スタートアップ。 最初からCIに統合された軽量で無料の静的解析ツールは安い保険であり、遺産のバックログが蓄積する機会を得る前に本物の問題を早期に捉えます。利用可能なすべてのルールを即座に有効にするのではなく、ルールセットを本物に高価値で低ノイズのカテゴリーに焦点を絞ってください。

中小企業。 ほとんどの現代的な言語のエコシステムには有能な無料の静的解析ツールが含まれています。賢明な既定のルールセットでそれをCIで有効にするのにほとんど投資は必要ありません。既存のバックログを一度にすべて解決しようとするのではなく、新しい発見をゲートすることに焦点を当ててください。

企業。 誤検知率と重要度のトリアージを意図的に管理することは、この規模で不可欠になります。なぜなら、調整の悪いツールが数十のチームにわたって過剰なノイズを生成すると、組織全体で無視されるからです。静的解析のツールの設定そのものに専任のオーナーに投資し、ルールの調整を一度きりのセットアップのタスクではなく継続的な規律として扱ってください。

政府。 静的解析の発見、特にセキュリティ関連のものは、しばしばコンプライアンスと監査の要件に直接関連しています。発見がどうトリアージされ、修正され、あるいは記録された正当化とともに正式に免除されるかについての、文書化され監査可能なプロセスを維持してください。なぜなら、この文書化そのものが、しばしば外部監査人が見たいと思うものだからです。

事例

企業。 あるソフトウェア企業の静的解析ダッシュボードは、重要度で重みづけされたトリアージなしに数年が経過した後、そのコードベース全体にわたって4万件を超える未解決の発見を蓄積しており、その数はあまりに大きかったため、エンジニアはダッシュボードをまったく見なくなっていました。改訂されたアプローチは発見を重要度によって分類し、本物に重大なものは200件未満であることを発見し、新しい重大かつ高重要度の発見について特にCIをゲートし、低重要度のバックログは通常のコード保守を通じて段階的に縮小させるままにしました。6か月以内に重大な発見は一桁にまで落ち、より重要なことに、エンジニアの調査データは、ツールが、圧倒的で無視されるバックログではなく、管理可能で本物に行動可能な信号を今では表面化させているため、ツールの出力への新たな信頼を示しました。

政府。 ある防衛機関のソフトウェアサプライチェーンセキュリティ方針は、どんなリリースの前にも未解決の発見がゼロであることを静的解析のスキャンに要求しており、この方針は実務において、実行不可能なオールオアナッシングのゲートのもとでリリースの締め切りを満たすためだけに、本物のセキュリティの問題のいくつかを含む多数の発見を開発チームに抑制させることにつながっていました。改訂された方針は、どんな特定のリリースによっても新しい重大あるいは高重要度の発見がゼロであることを要求し、四半期ごとにセキュリティガバナンス委員会によってレビューされる、遺産のバックログのための文書化され追跡された是正計画とスケジュールと組み合わせました。この実践的で段階的なアプローチは、新しいコードへの本物のセキュリティの精査を回復し、同時に18か月にわたって遺産のバックログに対する本物の測定可能な進歩を遂げました。これは、ほとんどが本物の修正ではなく抑制を生み出していた以前の実行不可能な方針とは対照的です。

ビジネスケース:動機、ROI、総所有コスト

よく管理された静的解析からの見返りは、同等のカバレッジのために同等の人間のレビューの努力が必要とするであろうものよりもはるかに低いコストで、本番に到達する前に本物の欠陥とセキュリティの脆弱性を捉えることです。上記の防衛機関の例は、これを間違えることのコストを示しています。実行不可能なオールオアナッシングの方針は、意図とは逆に、抑制を駆動することによって実際には本物のセキュリティの精査を減らしていたのです。

総所有コストには、しばしば一般的な言語のエコシステムでは無料か低コストであるツール自体と、重要度のトリアージ、誤検知の管理、そして遺産のバックログの是正計画の継続的な規律が含まれます。ツールそのものよりも、その継続的な規律こそが、静的解析のプログラムが本物で信頼される価値を提供するか、無視されるノイズへと退化するかを決定します。

アンチパターンと落とし穴

  • 素の発見件数を指標として扱う。 些細な問題と深刻な問題を混同し、抑制を通じて容易に操作されます。
  • 新しい仕事が進む前に歴史的なバックログ全体の解決を要求する。 通常非現実的であり、本物の修正ではなく抑制を駆動します。
  • 誤検知率を無視する。 管理されていないノイズのレベルは、チームにツールの出力全体を、本物の発見を含めて無視させることにつながります。
  • 正当な発見の静かで文書化されていない抑制。 ツールの信号を蝕み、コンプライアンスの目的のために監査証跡を残しません。
  • 静的解析の発見を人間のレビューなしの自動的な判決として扱う。 ツールが見られない文脈を見逃します。
  • 複雑さとホットスポットのデータと発見を一度も相互参照しない。 収束する証拠が提供するより強い優先順位づけの信号を見逃します。

成熟度モデル

  • レベル1、開始: 静的解析は実行されていないか、重要度のトリアージや傾向の追跡なしに発見が管理されないまま蓄積しています。
  • レベル2、発展: いくらかの静的解析がCIで実行されていますが、重要度のトリアージは一貫しておらず、誤検知率は管理されていません。
  • レベル3、標準化: 発見は重要度で重みづけされ、CIは組織全体で新しい重大かつ高重要度の発見についてゲートをかけます。
  • レベル4、管理: 誤検知率は能動的に調整され、遺産のバックログは文書化されペース配分された是正計画を持ち、免除は目に見えて文書化されています。
  • レベル5、最適化: 静的解析の発見、複雑さのデータ、ホットスポットのデータは投資を優先順位づけるために日常的に相互参照され、組織はこのプログラムにたどれる具体的で測定可能な欠陥やセキュリティの改善を指し示すことができます。

議論のためのアイデア

  1. 私たちの現在の重要度で重みづけされた傾向は何で、それは改善しているでしょうか、それとも悪化しているでしょうか。
  2. 私たちの遺産の発見のバックログはどれだけ大きく、私たちはそれを減らす意図的な計画を持っているでしょうか。
  3. 私たちの最も騒がしい発見のカテゴリーについて、私たちの推定誤検知率はどれだけでしょうか。
  4. 私たちのチームのエンジニアは現在、私たちの静的解析の出力を信頼しているでしょうか、それとも無視しているでしょうか。
  5. 私たちのコードベースのどこで、静的解析の発見は複雑さやホットスポットのデータと収束しているでしょうか。

主な要点

  • 些細な問題と深刻な問題を混同する素の発見件数ではなく、重要度で重みづけされた傾向を追跡してください。
  • 非現実的な一度きりの修正を要求することなく後退を防ぐために、歴史的なバックログ全体ではなく新しく導入された発見でCIをゲートしてください。
  • 誤検知率を能動的に管理してください。管理されていないノイズはツールへの信頼を破壊し、発見が全体として無視されることにつながります。
  • 発見を、自動的な判決や静かな抑制としてではなく、目に見える文書化された免除を伴う人間のレビューのための合図として扱ってください。
  • より収束的で強い優先順位づけの証拠のために、静的解析を複雑さとホットスポットのデータ(トピック4.1、トピック4.3)と相互参照してください。

参考文献とさらなる読書

  • Static Program Analysis, Anders Møller、Michael I. Schwartzbach 著。
  • セキュアなソフトウェア開発の慣行についてのより広いOWASP Foundationのリソースの一部である、静的アプリケーションセキュリティテスト(SAST)についてのOWASPの指針。
  • Refactoring: Improving the Design of Existing Code, Martin Fowler 著。
  • Working Effectively with Legacy Code, Michael Feathers 著。