脆弱性
ぜいじゃくせい
攻撃に悪用されうるソフトウェアの欠陥。CVEで番号づけされCVSSで深刻度が評価される。
概要
脆弱性(vulnerability)は、ソフトウェアやシステムに存在する欠陥のうち、攻撃者に悪用されうるものを指します。「バグ」の一種ではありますが、ただ動作がおかしいだけのバグとは区別されます。画面のレイアウトが崩れるバグは利用者を困らせるだけですが、入力チェックの漏れがSQLインジェクションにつながるなら、それは脆弱性です。分かれ目は「攻撃者がその欠陥を使って、本来できないはずのこと — データの窃取、権限の奪取、サービスの停止など — を実現できるか」にあります。
脆弱性はコードの実装ミスだけから生まれるわけではありません。設計上の見落とし、設定の誤り、古いライブラリの放置、さらには仕様そのものの欠陥も脆弱性になります。そして現代の開発では、自分が書いたコードよりも、依存しているライブラリやフレームワークに見つかる脆弱性への対応のほうが日常業務として頻繁に発生します。「Dependabot が警告を出した」「CVE-2021-44228(Log4Shell)の影響調査をしてほしい」といった場面で、CVE 番号や CVSS スコアを読み解く力が求められます。
なぜ生まれたか
脆弱性そのものは、ソフトウェアが存在する限り避けられない副産物です。しかし「脆弱性を識別し、管理する仕組み」は必要に迫られて作られました。1990年代、同じ欠陥がベンダーごと・ツールごとに別の名前で呼ばれ、「うちのスキャナが検出したこの問題は、あのアドバイザリの問題と同じものか?」を突き合わせることすら困難でした。この混乱を解消するため、1999年に MITRE 社が CVE(Common Vulnerabilities and Exposures)を開始し、公開された脆弱性一つひとつに世界共通の識別番号を与える体制が整いました。
もうひとつの課題は深刻度の伝え方です。「重大」「注意」といったベンダー独自の表現では横並びの比較ができません。そこで生まれたのが CVSS(Common Vulnerability Scoring System)で、攻撃のしやすさと影響の大きさを共通の基準で採点し、0.0〜10.0 のスコアに落とし込みます。番号で「どの脆弱性か」を特定し、スコアで「どれくらい急ぐべきか」を判断する — この2つの共通言語が、世界中の組織が同じ脆弱性情報を基に動くための土台になっています。
詳細
バグと脆弱性 — 悪用可能性という分かれ目
すべての脆弱性はバグ(広い意味での欠陥)ですが、すべてのバグが脆弱性ではありません。ある欠陥が脆弱性と呼ばれるのは、それを悪用する具体的な道筋 — エクスプロイトと呼ばれます — が成立しうるときです。たとえば境界チェックの漏れは、単にクラッシュするだけなら品質バグですが、攻撃者が細工した入力でメモリ上の任意のコードを実行できるなら深刻な脆弱性です。防御側にとって重要なのは、「動作に影響がないから放置してよい」とは限らないという視点です。一見無害な情報漏えい(エラーメッセージに内部パスが出る等)も、他の欠陥と組み合わされて攻撃の足がかりになります。
CVE と CVSS — 識別と深刻度の共通言語
CVE 番号は CVE-2021-44228 のように「CVE-西暦-連番」の形式で、公開された脆弱性を一意に識別します。採番は MITRE と、その権限を委譲された CNA(ベンダーやセキュリティ企業)が行い、米 NIST の NVD などのデータベースに詳細情報が蓄積されます。番号があることで、スキャナの検出結果、ベンダーのアドバイザリ、社内の対応チケットを同じ脆弱性として紐づけられます。
CVSS スコアを読むときは、数字だけを鵜呑みにしないことが大切です。基本スコアは「ネットワーク越しに攻撃できるか」「認証は必要か」「利用者の操作が要るか」といった攻撃の条件と、機密性・完全性・可用性への影響から機械的に算出された「その脆弱性自体の性質」です。9.8 という高スコアでも、該当機能を無効化していれば自社への影響はゼロかもしれませんし、5.0 台でも、インターネットに面した基幹システムに存在するなら最優先で対応すべきかもしれません。スコアはトリアージの出発点であり、自社環境での到達可能性と影響を重ねて優先度を決めるのが実務です。近年は「実際に悪用が観測されているか」(CISA の KEV カタログや EPSS スコア)を併用して優先順位を付ける手法も広まっています。
脆弱性情報のライフサイクル — 発見から公開まで
脆弱性は「発見された瞬間」ではなく「修正が行き渡る前に攻撃者に知られた瞬間」が最も危険です。そのため、発見者がベンダーに非公開で報告し、修正版が用意されてから詳細を公開する「協調的開示(coordinated disclosure、責任ある開示)」が業界の標準的な作法になっています。多くの組織は 90 日程度の猶予期間を設け、期限内に修正されない場合は利用者保護のために公開に踏み切る、というルールで運用しています。
この流れが崩れるケースが2つあります。ひとつは、修正が存在しないまま攻撃者が悪用を始める「ゼロデイ攻撃」です。防御側に対応猶予が0日しかないことが名前の由来で、パッチでは防げないため、WAF による仮想パッチ、最小権限による被害の局所化、監視による早期検知といった多層の備えが唯一の対抗手段になります。もうひとつは、修正版の公開そのものが攻撃者へのヒントになるケースです。パッチの差分から脆弱性を逆算した「Nデイ攻撃」は公開から数日以内に始まることが多く、「パッチが出たら速やかに当てる」体制の有無がそのまま防御力の差になります。
依存関係の脆弱性管理 — 現代の主戦場
現代のアプリケーションはコードの大半を外部ライブラリに依存しており、脆弱性対応の主戦場は「自分のコードのバグ修正」から「依存関係の把握と更新」に移っています。GitHub の Dependabot や各種 SCA(Software Composition Analysis)ツールは、ロックファイルから依存ツリーを読み取り、既知の CVE と突き合わせて警告と更新プルリクエストを自動生成します。これを CI/CD パイプラインに組み込み、日常的に小さく更新し続けることが、Log4Shell のような大規模事案の際に「自社のどこで使っているか分からない」という最悪の状態を避ける備えになります。依存関係そのものが改ざんされるサプライチェーン攻撃への警戒から、部品表(SBOM)を整備して依存を可視化する動きも広がっています。
脆弱性を「見つける」活動としては、OWASP Top 10 を指針にした設計レビュー、自動スキャンによる脆弱性診断、そして攻撃者の視点で実際に侵入を試みるペネトレーションテストがあり、それぞれ守備範囲が異なります。脆弱性は撲滅できるものではなく、発見・評価・修正のサイクルを回し続ける運用対象である — この認識が、防御側のすべての活動の前提になっています。