ソフトウェア開発において、リリース後に致命的な脆弱性が発見されることは、企業にとって計り知れないリスクです。情報漏洩、サービス停止、信頼の失墜。これらを防ぐには、開発段階で潜在的なバグやセキュリティホールを徹底的に洗い出す必要があります。
一口に「テスト」といっても、そのアプローチは多岐にわたります。ソースコードを一行ずつ確認するのか、実際にプログラムを動かして挙動を見るのか、予測不能なデータを投げつけて反応を見るのか。高度なセキュリティ人材を目指すうえでは、それぞれのテスト手法の特性を深く理解し、適切なフェーズで適切なツールを選定する能力が不可欠です。
本記事では、セキュリティ検査の主要な柱である「静的解析」「動的解析」「ファジング」について、その仕組みからメリット・デメリット、現場での活用シーンまでを網羅的に解説します。これらの手法をマスターすることは、堅牢なシステムを構築するための強力な武器となるでしょう。

脆弱性検出の基本概念とシフトレフト
セキュリティ対策において、最もコストパフォーマンスが良いのはいつでしょうか。答えは、システムの設計・開発段階です。リリース後に脆弱性が見つかり、修正パッチを配布し、ユーザーにアップデートを促すコストに比べれば、開発中にバグを潰しておくコストは微々たるものです。
この「開発工程の早い段階(左側)で品質を作り込む」という考え方をシフトレフトと呼びます。本記事で解説する3つの手法は、このシフトレフトを実現するための具体的な手段です。
ホワイトボックステストとブラックボックステスト
各手法の詳細に入る前に、テストの視点について整理しましょう。テストは大きく2つの視点に分類されます。
ホワイトボックステストは、内部構造(ソースコードやロジック)を把握したうえで行うテストです。開発者自身が実施することが多く、網羅的な検証が可能です。静的解析は主にこのカテゴリに分類されます。
ブラックボックステストは、内部構造を考慮せず、外部から入力を行い、出力や挙動を確認するテストです。攻撃者の視点に近く、実際の運用環境での振る舞いを検証できます。動的解析やファジングは、この要素を強く持ちます。
これらは対立するものではなく、補完し合う関係にあります。内部から論理的な整合性を確認し、外部から攻撃者の視点で隙を突く。この両輪が揃って初めて、強固なセキュリティが実現します。
静的解析(Static Analysis):コードに潜む病巣を早期発見
静的解析とは、プログラムを実行することなく、ソースコードやコンパイルされたバイナリを解析して問題点を発見する手法です。「静的コード解析」とも呼ばれます。
文章の校正ツールやスペルチェッカーをイメージするとわかりやすいでしょう。プログラムが実際に動くかどうかに関わらず、記述されたロジックや構文のパターンから、バグや脆弱性の原因となりそうな箇所を指摘します。
静的解析のメカニズムと具体的手法
静的解析ツールは、単なる文字列検索以上の高度な処理を行います。以下が主な解析手法です。
字句解析・構文解析では、コンパイラと同じようにコードを読み込み、構造を理解します。
データフロー解析(テイント解析)では、外部からの入力データ(信頼できないデータ)が、サニタイズ(無害化)されずに、SQL発行処理やHTML出力処理などの危険な箇所(シンク)に到達していないかを追跡します。
コントロールフロー解析では、プログラムの処理経路を分析し、到達不可能なコードや、初期化されていない変数の使用などを検出します。

静的解析のメリット
静的解析には以下の強みがあります。
- 網羅性が高い: 実行時には通らないようなレアな分岐ルートも含め、コード全体を検査できます
- 早期発見: コードを書いている最中や、コンパイル時に実施できるため、修正コストが極めて低くなります
- 環境構築が不要: 実行環境やテストデータを用意する必要がありません
静的解析のデメリットと課題
一方で、以下のような課題も存在します。
過検知(False Positive)が発生しやすく、実際には問題ない箇所を「脆弱性あり」と誤って警告することがあります。解析ツールは「疑わしきは罰する」傾向があるため、大量の警告の中から真の問題を見極めるスキルが必要です。
論理エラーの検出は苦手で、「仕様通りの動きだが、仕様自体がセキュリティ的に問題がある」といったビジネスロジックの不備は見つけにくい傾向があります。
動的解析(Dynamic Analysis):稼働中の挙動を監視
動的解析は、プログラムを実際に実行し、その挙動を観測することで問題点を発見する手法です。実際に車を走らせて、異音がしないか、ブレーキが効くかを確認するテストドライブに似ています。
Webアプリケーション診断などで、プロキシツールを用いてパラメータを操作し、サーバーからの応答を確認する行為も動的解析の一種です。
動的解析のアプローチ
動的解析には、デバッガを用いた詳細な解析から、専用のスキャナを用いた自動診断まで幅広く存在します。
メモリ監視では、プログラム実行中のメモリ使用状況を監視し、バッファオーバーフローやメモリリークが発生していないかを確認します。
通信監視では、ネットワークパケットをキャプチャし、意図しない通信や暗号化されていない通信が行われていないかを確認します。
サンドボックスは、マルウェア解析などで用いられる手法で、隔離された仮想環境内でプログラムを実行し、システムファイルへの不正な書き込みや不審なプロセス起動などを観察します。
動的解析のメリット
動的解析には以下の強みがあります。
- 実環境に近い: 実際に動作させるため、OSやライブラリとの相性問題など、静的解析では見えない問題を発見できます
- 過検知が少ない: エラーが発生したということは、実際にその現象が起きているため、静的解析に比べて「誤報」である確率は低くなります
動的解析のデメリット
一方で、以下のような課題があります。
網羅性の確保が困難で、テストを実行したパス(経路)しか検証できません。条件分岐が複雑なプログラムの場合、すべてのルートを通るようなテストデータを作成するのは至難の業です。
実行環境の準備が必要で、データベースやネットワークなど、動作に必要な環境をすべて整える必要があります。
危険性も伴います。実際に攻撃コードを送る場合、データ破壊やシステム停止のリスクがあるため、本番環境での実施には細心の注意が必要です。
ファジング(Fuzzing):予期せぬ入力でクラッシュを誘発
ファジング(Fuzz testing)は、予測不可能なデータ(ファズ)を大量に対象プログラムに入力し、例外処理の不備やクラッシュ、メモリ破壊などを引き起こすかどうかを検証するテスト手法です。動的解析の一種ですが、その特異なアプローチから独立して扱われることが多くなっています。
「人間なら絶対に入力しないようなデタラメなデータ」を入力することで、開発者が想定していなかったバグをあぶり出します。未知の脆弱性(ゼロデイ脆弱性)の発見において、現在最も成果を上げている手法の一つです。

ファジングの種類と仕組み
ファジングは、データの生成方法によって大きく2つに分類されます。
変異型(Mutation-based)は、有効な入力データ(正常なファイルなど)をベースに、一部のビットを反転させたり、データを切り詰めたり、極端に長い文字列を挿入したりして「変異」させたデータを生成します。フォーマットがある程度保たれているため、入力チェックをすり抜けて深部の処理に到達しやすいというメリットがあります。ただし、ベースとなるサンプルデータが必要です。
生成型(Generation-based)は、プロトコルやファイルフォーマットの仕様(文法)に基づいて、ゼロからデータを生成します。仕様の境界値テストなどに強く、網羅的なデータを生成できますが、対象の仕様を正確に定義する必要があり、準備に手間がかかります。
インテリジェントなファジング(カバレッジガイド)
初期のファジングは完全にランダムなデータを投げるだけでしたが、現代のファジングツール(AFL: American Fuzzy Lopなど)は非常に賢くなっています。
これらはコードカバレッジ(網羅率)を計測しながら動作します。あるデータを入力した結果、新しいコードパス(これまで実行されていなかったif文の中など)を通った場合、そのデータを「有望なデータ」として保存し、それをベースにさらに変異を加えます。これにより、効率的にプログラムの深部まで探索することが可能になります。
ファジングで見つかる脆弱性
ファジングは特に、C言語やC++などで記述されたネイティブアプリケーションの脆弱性発見に威力を発揮します。
バッファオーバーフローは、入力データが確保されたメモリ領域を超えて書き込まれるバグです。
整数オーバーフローは、数値計算の結果が型の最大値を超え、意図しない値になるバグです。
メモリリーク/不正なメモリアクセスは、解放済みのメモリを使おうとする(Use-after-free)などのバグです。
DoS(サービス拒否)は、特定の入力で無限ループに陥ったり、リソースを食いつぶしたりする問題です。
各手法の比較と統合的な活用戦略(SAST / DAST / IAST)
ここまで解説した手法は、それぞれ得意分野が異なります。実際の開発現場やセキュリティ監査では、これらを組み合わせることが重要です。業界では以下のような略語で呼ばれることもあります。
SAST(Static Application Security Testing)は静的解析で、開発初期に実施されます。
DAST(Dynamic Application Security Testing)は動的解析で、QA環境やステージング環境で実施されます。
IAST(Interactive Application Security Testing)は、エージェントを組み込み、動的テスト中に静的な情報(コード行数など)も取得して分析する手法です。SASTとDASTのハイブリッドといえます。
手法別比較表
| 特徴 | 静的解析 (SAST) | 動的解析 (DAST) | ファジング |
|---|---|---|---|
| 実施タイミング | コーディング~ビルド時 | テスト~運用時 | テスト時 |
| 対象 | ソースコード | 実行アプリケーション | 実行アプリケーション |
| 網羅性 | 高い(全パス解析可能) | 低い(実行パスのみ) | 中~高(時間依存) |
| 誤検知 | 多い(過検知) | 少ない | 少ない(クラッシュは事実) |
| 得意なバグ | コーディング規約違反、XSS、SQLiのパターン | 設定ミス、認証認可の不備 | メモリ破損、例外処理不備 |
| コスト | 低(自動化容易) | 中(環境構築必要) | 高(計算リソース必要) |
DevSecOpsへの統合
近年では、DevOps(開発と運用の連携)にセキュリティを統合したDevSecOpsという考え方が主流です。
コードをコミットした瞬間に静的解析が走り、基本的なミスを指摘します。夜間のビルド時にファジングを回し続け、朝にはクラッシュレポートが届いています。リリース前の最終確認で動的解析スキャンを行い、Web脆弱性をチェックします。
このように、CI/CDパイプライン(継続的インテグレーション/デリバリー)の中にこれらのツールを自動的に組み込むことで、開発スピードを落とさずにセキュリティ品質を担保することが可能になります。情報処理安全確保支援士などの試験においても、このような「プロセスの自動化」や「ツールの使い分け」に関する出題は頻出です。
セキュリティテストツールの実例と選定ポイント
理論だけでなく、実際に使われているツールを知ることで、理解が深まります。ここでは代表的なツールと、選定時のポイントを紹介します。
静的解析ツールの代表例
商用ツールとしては、Checkmarx、Fortify、Veracodeなどが企業で広く採用されています。これらは精度が高く、多言語対応で、誤検知を減らすチューニング機能も充実しています。
オープンソースツールでは、SonarQubeが有名です。コードの品質管理とセキュリティチェックを統合的に行え、CI/CDパイプラインに組み込みやすい特徴があります。また、言語ごとに特化したツール(例:Pythonのbandit、JavaのSpotBugs)も存在します。
動的解析ツールの代表例
Webアプリケーション診断では、OWASP ZAP(無料)やBurp Suite(有料版が高機能)が定番です。プロキシとして動作し、通信を傍受・改ざんして脆弱性を探します。
APIテストでは、Postmanにセキュリティテスト機能を追加したり、専用ツールのImperial-APIを使用したりします。
インフラ診断では、NessusやOpenVASなどの脆弱性スキャナが使われます。既知の脆弱性データベース(CVE)と照合し、パッチ未適用の脆弱性を検出します。
ファジングツールの代表例
AFL(American Fuzzy Lop)は、カバレッジガイドファジングの先駆けで、多くの重大な脆弱性を発見してきました。Linuxのバイナリを対象とし、コンパイル時に計測コードを埋め込むことで効率的なファジングを実現します。
libFuzzerは、LLVMプロジェクトの一部で、AFL同様にカバレッジガイドですが、プロセス内で実行されるため高速です。
Peach Fuzzerは、生成型ファジングに強く、複雑なプロトコルやファイルフォーマットの仕様を定義してテストできます。
OSS-Fuzzは、Googleが提供するクラウド型のファジングサービスで、主要なオープンソースプロジェクトに対して継続的にファジングを実施しています。
ツール選定時の考慮事項
ツールを選ぶ際は、以下のポイントを検討しましょう。
対応言語と環境を確認します。開発に使用している言語やフレームワークに対応しているか、クラウド環境やコンテナ環境で動作するかをチェックします。
CI/CD統合のしやすさも重要です。Jenkins、GitLab CI、GitHub Actionsなど、使用しているCI/CDツールと連携できるか確認します。
誤検知率と検出力のバランスを評価します。誤検知が多すぎると開発者が疲弊し、少なすぎると見逃しが増えます。試用期間を設けて自社のコードで評価することが理想的です。
コストと体制も考慮が必要です。ライセンス費用だけでなく、導入・運用にかかる人的コストも含めて検討します。専任のセキュリティチームがいない場合は、運用負荷の低いSaaS型ツールが適しています。
レポート機能と開発者への通知も大切です。発見された問題を開発者にわかりやすく伝え、修正につなげる仕組みが重要です。
実践的なセキュリティテスト戦略の構築
理論と具体的なツールを理解したところで、実際のプロジェクトでどのように活用するかを考えましょう。
開発ライフサイクルごとの適用戦略
要件定義・設計フェーズでは、脅威モデリング(STRIDE、ATTACKモデル)を実施し、想定される攻撃シナリオを洗い出します。この段階では、アーキテクチャレベルでのセキュリティ設計が重要です。
実装フェーズでは、開発者のIDEに静的解析プラグインを導入し、コーディング中にリアルタイムで問題を指摘します。また、コミット時に自動で静的解析を実行し、問題があればマージをブロックする仕組みを構築します。
テストフェーズでは、QA環境で動的解析スキャンを実施し、認証・認可の不備や設定ミスを検出します。また、ファジングを夜間バッチで実行し、メモリ破壊系の脆弱性を探します。
リリース前には、ペネトレーションテスト(侵入テスト)を実施し、人手による高度な検証を行います。これは自動ツールでは検出困難な、複数の脆弱性を組み合わせた攻撃シナリオを検証します。
運用フェーズでは、WAF(Web Application Firewall)のログを分析し、実際の攻撃トレンドを把握します。また、バグバウンティプログラムを活用し、外部のセキュリティ研究者からの報告を受け付けます。
誤検知との戦い方
静的解析ツールの最大の課題である誤検知(False Positive)にどう対処するかは、導入成功の鍵を握ります。
ベースライン設定として、初回スキャン時の警告をすべて精査し、真の問題と誤検知を分類します。誤検知については、ツールのルールをカスタマイズしたり、特定のコード箇所を除外リストに追加したりします。
段階的な導入も有効です。最初は重大度「高」の問題だけに集中し、徐々に「中」「低」の問題にも取り組みます。すべての警告に一度に対処しようとすると、開発チームが疲弊してしまいます。
開発者教育も重要です。なぜその警告が出るのか、どのような脅威につながるのかを理解することで、誤検知か真の問題かを判断する能力が向上します。
定期的な見直しとして、ツールのルール設定を定期的に見直し、新たな脆弱性パターンに対応します。また、誤検知として除外したものが、ライブラリのアップデートなどで実際の問題になっていないか確認します。
セキュリティテストの自動化と継続的改善
CI/CDパイプラインにセキュリティテストを組み込むことで、「セキュリティゲート」を設けます。一定以上の脆弱性が検出された場合、自動的にビルドを失敗させ、本番環境へのデプロイを防ぎます。
メトリクスの可視化も効果的です。発見された脆弱性の数、種類、修正までの時間などをダッシュボードで可視化し、セキュリティ品質の推移を追跡します。これにより、改善の効果が目に見える形で確認できます。
フィードバックループの構築として、発見された脆弱性から学び、コーディングガイドラインやセキュアコーディング研修に反映します。同じ種類の問題が繰り返し発見される場合、根本的な教育や開発プロセスの見直しが必要です。
セキュリティテストの限界と補完策
どれほど高度なツールを使っても、完璧なセキュリティは存在しません。テストツールの限界を理解し、他の対策と組み合わせることが重要です。
テストツールが苦手とする領域
ビジネスロジックの欠陥は、ツールでは検出困難です。例えば、「ポイントを使った購入でマイナスのポイントを指定すると、逆にポイントが増える」といった仕様上の問題は、人間による論理的な思考が必要です。
認証・認可の複雑な不備も難しい領域です。「ユーザーAがユーザーBのデータを閲覧できてはいけない」といった権限設計の問題は、テストシナリオを綿密に設計する必要があります。
タイミング依存の問題(レースコンディション)は、再現性が低く検出が困難です。マルチスレッド環境での同時アクセスによる不整合などは、専用のテスト設計が必要です。
サードパーティライブラリの脆弱性については、SCA(Software Composition Analysis)ツールで既知の脆弱性を検出できますが、ライブラリの使い方に起因する問題は別途検証が必要です。
多層防御の考え方
テストで脆弱性を100%排除することは不可能です。そのため、多層防御(Defense in Depth)の考え方が重要になります。
予防的統制として、セキュアコーディング教育、設計レビュー、静的・動的解析を実施します。
検知的統制として、WAF、IDS/IPS、ログ監視、異常検知システムを導入します。
是正的統制として、インシデント対応計画、バックアップ、復旧手順を準備します。
この3層が連携することで、一つの防御が破られても、次の防御が機能する仕組みを構築します。
試験対策と実務への応用
情報処理安全確保支援士などの試験においては、これらの技術の定義を問う問題だけでなく、「ある状況下でどのツールを採用すべきか」「ツールの出力結果から何が読み取れるか」といった実践的な知識が問われます。
試験での頻出ポイント
フォールスポジティブとフォールスネガティブの違いは頻出です。静的解析は「誤検知(フォールスポジティブ)」が多く、開発者が疲弊しないようフィルタリングやルールのチューニングが必要です。動的解析は「見逃し(フォールスネガティブ)」が発生しやすく、カバレッジをどう上げるかが課題です。
具体的な脆弱性との関連も重要です。バッファオーバーフロー対策として、コンパイル時の防御策(静的)と、ASLRなどの実行時防御策(動的)があるように、発見手法も対になっています。SQLインジェクションやクロスサイトスクリプティング(XSS)は、静的解析でも動的解析でも発見可能ですが、検出のアプローチが異なることを理解しておきましょう。
WAFやIPSとの違いも明確にしておく必要があります。本記事で紹介したのは「脆弱性を発見する(検査)」技術です。一方、WAFやIPSは「攻撃を防ぐ(防御)」技術です。検査で見つかった脆弱性を根本修正するまでの間、WAFで攻撃を防ぐ(バーチャルパッチ)といった連携も実務では重要になります。
各手法の実施タイミングについても問われます。シフトレフトの観点から、静的解析は開発早期、動的解析はテスト段階、ファジングは継続的に実施、という基本パターンを押さえておきましょう。
実務で求められるスキル
試験合格はゴールではなく、スタートです。実務で活躍するために以下のスキルを磨きましょう。
ツールの出力を読み解く力は必須です。静的解析ツールが出力する膨大な警告から、優先度の高い問題を見極める判断力が求められます。CVSSスコア、攻撃の容易性、影響範囲などを総合的に評価します。
修正方針を提案する力も重要です。単に「脆弱性がある」と指摘するだけでなく、「この箇所をこう修正すべき」「この対策を講じるべき」という具体的な改善案を示せることが、セキュリティ専門家の価値です。
開発チームとのコミュニケーション能力も欠かせません。セキュリティの専門用語を使わず、開発者が理解できる言葉で説明し、協力を得る能力が必要です。「セキュリティのために開発を遅らせる人」ではなく、「セキュリティを考慮しながら開発を加速する人」を目指しましょう。
最新の脅威動向のキャッチアップも継続的に行う必要があります。新たな攻撃手法が日々登場する中、ツールのアップデート情報、CVE情報、セキュリティカンファレンスの発表などを追い続けることが重要です。
最新トレンドと今後の展望
セキュリティテストの分野も、技術の進化とともに変化しています。今後注目すべきトレンドを紹介します。
AI/機械学習の活用
静的解析における誤検知削減に、機械学習が活用され始めています。過去の警告データと、実際に脆弱性だったかどうかのデータを学習させることで、より精度の高い検出が可能になっています。
ファジングにおいても、生成するデータをAIが最適化し、効率的に脆弱性を発見する研究が進んでいます。ランダムではなく、「この値を変えたら深い処理に到達しそう」という予測に基づいてデータを生成します。
コンテナ・クラウドネイティブ環境への対応
Dockerコンテナのイメージスキャン、Kubernetes設定の脆弱性チェックなど、クラウドネイティブ環境特有のセキュリティテストツールが充実してきています。TrivyやClairなどのコンテナスキャナは、ベースイメージに含まれる脆弱性を自動検出します。
Infrastructure as Code(IaC)の普及により、TerraformやCloudFormationテンプレートの静的解析も重要になっています。設定ミスによるセキュリティホールを、デプロイ前に発見できます。
シフトレフトからシフトエブリウェアへ
開発の早期段階だけでなく、あらゆる段階でセキュリティを考慮する「シフトエブリウェア」という考え方が広がっています。開発中、テスト中、リリース後、すべてのフェーズで継続的にセキュリティを検証し続けます。
SBOMとサプライチェーンセキュリティ
SBOM(Software Bill of Materials:ソフトウェア部品表)の整備が進んでいます。使用しているライブラリやコンポーネントを明確にリスト化することで、脆弱性が発見された際に、自社製品への影響を迅速に評価できます。
Log4Shell(Log4jの脆弱性)のような広範囲に影響する脆弱性が発見されたとき、SBOMがあれば「自社のどの製品が影響を受けるか」を即座に特定できます。
実践!脆弱性を見抜く「入力と出力」の練習問題
ここまで解説してきた「入り口(検証)」と「出口(エスケープ)」の鉄則が、実際の判断として身についているかを確認してみましょう。
以下の練習問題は、SQLインジェクションやXSS、OSコマンドインジェクションといった主要な脆弱性を防ぐための「正しい実装手順」や「考え方」にフォーカスしています。これらは試験だけでなく、実際の開発現場やコードレビューでも即座に役立つ知識です。
全10問の選択式です。選択肢を選ぶと、その選択肢が適切(または不適切)である理由が表示されます。「ヒント」も活用しながら、満点を目指してチャレンジしてください。
まとめ
本記事では、ソフトウェアの堅牢性を高めるための3つのアプローチ、「静的解析」「動的解析」「ファジング」について、詳細に解説しました。
静的解析は、コードの設計図を見て、論理的な誤りや危険なパターンを早期に見つけ出す「校閲者」です。網羅性は高いですが、誤検知との戦いが必要です。開発の最も早い段階で実施できるため、修正コストを最小化できます。
動的解析は、実際に動かして外部から振る舞いを観察する「監査官」です。現実的な脅威を検出できますが、すべてのルートを通すのは困難です。実行環境での動作を確認できるため、環境依存の問題を発見できます。
ファジングは、想定外の入力を投げつけ、システムの耐久性を試す「破壊者」であり「実験者」です。未知の脆弱性発見に強力な威力を発揮します。開発者が想定していなかった入力パターンでバグをあぶり出します。
重要なのは、これらに優劣をつけることではなく、適材適所で組み合わせることです。開発ライフサイクルの各フェーズで、何を守るために、どの程度の深さで検査が必要なのか。その目的意識を持ってツールを選定できるエンジニアこそが、真のセキュリティスペシャリストといえるでしょう。
セキュリティの世界は「攻撃者有利」といわれます。攻撃者はたった一つの穴を見つければ良いのに対し、守る側はすべての穴を塞がなければならないからです。しかし、これらの高度な解析技術を駆使し、自動化を進めることで、その非対称性を少しでも埋め、攻撃者が諦めるような堅牢なシステムを構築することは可能です。
現代のソフトウェア開発において、セキュリティは「後から追加するもの」ではなく、「最初から組み込むもの」です。DevSecOpsの文化を醸成し、開発者全員がセキュリティを意識する体制を構築することが、組織全体のセキュリティレベル向上につながります。
まずは、手近なオープンソースの静的解析ツールを自分のコードにかけてみることから始めてみてはいかがでしょうか。画面に並ぶ警告の一つ一つが、あなたのセキュリティスキルを向上させるための最良の教材になるはずです。そして、それぞれの警告の意味を理解し、適切に対処できるようになったとき、あなたはすでに一歩先のセキュリティエンジニアになっているでしょう。