日々発表されるハイリスクな脆弱性に対応されている皆様、本当にお疲れ様です。
ところで皆様は、npm install(もしくはpip installやcomposer installなど)を実行した回数を覚えていらっしゃいますか。
私は覚えていません。
回数だけでなく、どのアプリに何を入れたかも、すべては把握できていませんでした。
npm installで作ったアプリ、その後は?
AIと一緒に開発するようになって、アプリを作る機会が増えました。
npm installをして、動かして、試してみる。そうやって作ったアプリが、ローカルのあちこちにあります。
ただ、何かのパッケージに脆弱性が見つかったとき、「自分のどのアプリが、そのパッケージを使っているのか」と聞かれると、すぐには分かりません。
直接入れたパッケージだけでなく、そのパッケージが内部で使っているものもあります。アプリが増えるほど、手作業では追いにくくなります。
そんなとき、既知の脆弱性を調べるために使えるサービスが、OSV.devです。
OSV.devについて
OSV.dev(Open Source Vulnerabilities)は、オープンソースの脆弱性情報を集約し、人やツールが調べられるようにした公開サービスです。
Googleのセキュリティチームが、2021年2月に公開しました。「脆弱性のニュースは出ているけれど、自分が使っているバージョンに関係するのか分かりにくい」という問題を解決するために始まりました。
どこから情報を集めているのか
Googleだけが調査した情報ではありません。GitHub Security Advisories、PythonのPyPA、RustのRustSecなど、さまざまな組織やコミュニティの脆弱性情報を集約しています。
npm、PyPI、Packagist、crates.ioなど、複数のパッケージの仕組みに対応しています。
パッケージ名とバージョンから調べられる
特徴は、脆弱性をパッケージ名やバージョンと結び付けて調べられること。「問題が報告されている」というニュースから一歩進んで、自分が使っているバージョンが該当するかを確認するために使えます。
参考:OSV公式FAQ
OSV.devの使い方
利用方法は、大きく3つあります。
Webサイトで調べる
OSV.devの「Search Vulnerability Database」から脆弱性情報を検索できます。個別の記録では、問題の内容、影響範囲、修正情報、元の情報源へのリンクなどを確認できます。
OSV-Scannerで手元のアプリを確認する
OSV.devの情報を使って、手元のプロジェクトを確認できる公式ツールが「OSV-Scanner」です。
対応する依存関係ファイルなどを読み、使っているパッケージを脆弱性情報と照合します。
例えば、npmのpackage-lock.jsonにはパッケージとバージョンが記録されています。対応ファイルに記録されていれば、直接入れたものだけでなく、そのパッケージが内部で使っているものも確認対象になります。
APIを自作ツールから使う
APIは、プログラムからOSV.devに問い合わせるための窓口です。パッケージの種類・名前・バージョン、またはコミットの識別情報などを指定し、該当する脆弱性情報を取得できます。
そのため、公式のOSV-Scannerを使うだけでなく、自分に必要な画面や管理機能を持つツールを作ることもできます。
OSV-Scannerでアプリを調べる
まずは、OSV-Scannerを使って手元のアプリを確認してみます。Windows・Macの両方で使えます。
インストールする
Windows
「PowerShell」を開き、次を実行します。
winget install Google.OSVScanner
インストール後、PowerShellを開き直します。
Mac
「ターミナル」を開き、次を実行します。
brew install osv-scanner
MacはHomebrewが必要です。まだ入れていない場合は、Homebrew公式サイトの案内を確認してください。
アプリのフォルダを指定する
インストールできたら、次のコマンドで確認します。
osv-scanner scan source -r "アプリのフォルダのパス"
Windowsの例:
osv-scanner scan source -r "C:\Users\YourName\my-app"
Macの例:
osv-scanner scan source -r "$HOME/projects/my-app"
指定するのは、ソースコードを保存しているフォルダです。-rを付けると、子フォルダも含めて確認します。
ターミナルやPowerShellで、調べたいアプリのフォルダを開いている場合は、次のコマンドでも実行できます。./は現在のフォルダを表します。
osv-scanner scan source -r ./
複数のアプリを同じ親フォルダに置いているなら、その親フォルダを指定する方法もあります。範囲が広いほど時間がかかるため、最初はアプリ1つで試すと結果を確認しやすいです。
なお、既定では.gitignoreで除外されたファイルは検査されません。-rを付けても、すべてのファイルを漏れなく調べるわけではありません。
参考:公式のスキャン手順
使用時サンプル
手元にあったWordPress関連プロジェクトのフォルダをスキャンしてみました。
今回のログでは、package-lock.jsonに記録されたnpmパッケージが検査対象になっています。WordPress本体やPHP、プラグイン全体の安全性を確認した結果ではありません。
以下は実行結果の抜粋です。パスの一部は伏せています。検出件数や修正版の情報は、スキャン時点のデータに基づくもので、再実行すると変わることがあります。
Scanned /Users/**/wp-sites/****/package-lock.json file and found 1534 packages
Total 14 packages affected by 22 known vulnerabilities (0 Critical, 7 High, 10 Medium, 5 Low, 0 Unknown) from 1 ecosystem.
21 vulnerabilities can be fixed.
╭─────────────────────────────────────┬──────┬───────────┬───────────────────────────────┬─────────┬───────────────┬───────────────────╮
│ OSV URL │ CVSS │ ECOSYSTEM │ PACKAGE │ VERSION │ FIXED VERSION │ SOURCE │
├─────────────────────────────────────┼──────┼───────────┼───────────────────────────────┼─────────┼───────────────┼───────────────────┤
│ https://osv.dev/GHSA-27r3-jxmh-p828 │ 7.5 │ npm │ body-parser (dev) │ 1.20.8 │ 1.20.9 │ package-lock.json │
│ https://osv.dev/GHSA-gcqx-w48m-w2h4 │ 5.3 │ npm │ deepmerge │ 4.3.1 │ -- │ package-lock.json │
│ https://osv.dev/GHSA-333x-w4r6-6crp │ 3.7 │ npm │ fast-uri (dev) │ 3.1.8 │ 3.1.9 │ package-lock.json │
...
14個のパッケージについて、22件の既知の脆弱性が報告されました。
結果には、次のような情報が表示されます。下の表は、実行ログの一部を読みやすく整理したものです。
| パッケージ | 記録されたバージョン | 修正版の表示 | 脆弱性情報 |
|---|---|---|---|
| body-parser (dev) | 1.20.8 | 1.20.9 | 詳細 |
| deepmerge | 4.3.1 | -- | 詳細 |
| uuid (dev) | 8.3.2 | 11.1.1 | 詳細 |
元の出力にある各項目は、次の意味です。
-
OSV URL:脆弱性情報の詳細ページ -
CVSS:脆弱性の重大度を表すスコア。自分のアプリへの影響は、使用条件も踏まえて確認します。 -
ECOSYSTEM:npmなど、パッケージの仕組みの区分 -
PACKAGE:該当するパッケージ。(dev)は開発用依存の区分で、影響がないという意味ではありません。 -
VERSION:依存関係ファイルに記録されたバージョン -
FIXED VERSION:修正版の情報。--でも、対策が不要という意味ではありません。 -
SOURCE:検出元のファイル
AIと一緒に修正する
脆弱性が見つかったら、対象のパッケージや修正版の情報を確認します。
この結果をAIに渡し、どの依存関係から入ったパッケージなのか、どの更新で解消できるのかを調べてもらう方法もあります。変更内容と互換性への影響を確認してから修正し、動作確認と再スキャンを行います。
修正後、同じコマンドでもう一度確認しました。
osv-scanner scan source -r ./
結果の抜粋です。
Scanned /Users/**/wp-sites/****/package-lock.json file and found 1546 packages
Total 3 packages affected by 3 known vulnerabilities (0 Critical, 1 High, 1 Medium, 1 Low, 0 Unknown) from 1 ecosystem.
2 vulnerabilities can be fixed.
残った検出結果は、次の3件でした。
| パッケージ | 記録されたバージョン | 修正版の表示 |
|---|---|---|
| deepmerge | 4.3.1 | -- |
| katex (dev) | 0.16.47 | 0.18.2 |
| uuid (dev) | 8.3.2 | 11.1.1 |
再スキャンでは、検出結果が22件から3件に減りました。
残った3件については、使っていないテーマや未使用のパッケージに由来するとの説明がありました。ただし、このログだけでは使用状況や影響の有無までは判断できません。実際にどこで使われ、公開先や開発環境にどう影響するかを確認する必要があります。
次は、自分のAIにツールを作ってもらう
一度調べることができたら、次は自分が管理しやすい形にしてみるのもよいと思います。
例えば、普段使っている開発用のAIに、こう依頼します。
OSVで脆弱性を調べるツールを作って。ローカルにある自作アプリを登録して、使っているパッケージの既知の脆弱性と、対応状況を一覧で確認できるようにしたい。外部に送信する情報は実行前に確認できるようにして。パッケージの更新は自動で行わないで。
OSV.devには、プログラムから問い合わせるためのAPIがあります。自作ツールからパッケージ名やバージョンを送り、該当する脆弱性情報を取得できます。
最初から大きなものを作る必要はありません。スキャン結果を見やすく表示するだけでも、自分にとって使いやすい道具になります。
アプリが増えてきたら、フォルダの登録や検索、対応メモなど、必要になった機能を足していけます。
ただし、チェック用のツールも、対象ファイルを読み落としたり、通信エラーを「問題なし」と扱ったりする可能性があります。AIに作ってもらった後は、何を確認できたのか、何が未確認なのかを区別して表示できるか、確かめてください。
何が分かり、何が分からないのか
OSV.devで確認できるのは、収録された情報に基づく既知の脆弱性です。
アプリを攻撃して問題を探すサービスでも、ソースコードを読んで未知の不具合を見つけるサービスでもありません。認証や権限の不備、APIキーの混入などは、別の確認が必要です。
また、未発見の脆弱性や未収録の情報もあります。照会結果が0件であることと、安全であることは同じではありません。見つかった問題についても、自分のアプリでの使い方や公開状況を踏まえて影響を確認します。
PHPやNode.js本体の更新状況、実際の公開先への修正反映も、依存パッケージのチェックとは別に確認してください。
対策を継続していこう
OSV.devは、自分が使っているオープンソースについて、報告済みの問題を調べ、更新や対応の判断に役立てるためのサービスです。
まずは、手元のアプリを1つ調べてみてはいかがでしょうか。
必要に応じて、動作中のWebアプリを調べるZAPなどの診断ツールや、コードレビューも組み合わせながら、継続して対策していきましょう。ZAPで検査する場合は、自分が検査する権限を持つ環境を対象にしてください。
まだまだ続く脆弱性ラッシュを乗り越えていきましょう!
現在、OSV.devを活用したローカルプロジェクト脆弱性チェックツールを開発中です。
正式に公開次第またQiitaに投稿したいと思います。