osv-scanner-mcp 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1
- package/dist/index.js +3 -1
- package/dist/osv/binaryManager.js +15 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ Google製 [OSV-Scanner](https://github.com/google/osv-scanner) をラップす
|
|
|
22
22
|
- [OSV-Scanner](https://google.github.io/osv-scanner/) バイナリ — **手動インストールは不要です**。見つからない場合、公式GitHub Releasesからピン留めバージョンを自動ダウンロードし、パッケージに埋め込まれたSHA256チェックサムで検証してから使用します(`~/.cache/osv-scanner-mcp/` にキャッシュ)
|
|
23
23
|
- 手動インストール済みのバイナリ(PATH上または `OSV_SCANNER_PATH` 指定)があればそちらを優先します
|
|
24
24
|
- 自動ダウンロードを無効化する場合は `OSV_MCP_AUTO_DOWNLOAD=0`
|
|
25
|
+
- PATH上のバイナリを使わず常に検証済み自動ダウンロードを使う場合は `OSV_MCP_PREFER_DOWNLOAD=1`(運用環境向け)
|
|
25
26
|
- スキャン時(OSV-Scanner経由)および `explain_vulnerability` 実行時に `api.osv.dev` へのネットワークアクセスが発生します(照会先はOSVデータベースのみ)
|
|
26
27
|
|
|
27
28
|
## セットアップ
|
|
@@ -119,9 +120,15 @@ npm run build
|
|
|
119
120
|
| `OSV_MCP_REQUIRE_ALLOWED_ROOT` | `1` または `true` 指定時、`OSV_MCP_ALLOWED_ROOT` が未設定ならサーバーの起動自体を拒否します(運用環境向けのfail-closedモード) |
|
|
120
121
|
| `OSV_MCP_MAX_CONCURRENT_SCANS` | 同時実行できるスキャン数の上限(デフォルト `2`、最大 `16`)。超過したリクエストは待たずに即時エラーになります |
|
|
121
122
|
| `OSV_MCP_AUTO_DOWNLOAD` | `0` または `false` でバイナリの自動ダウンロードを無効化(デフォルト有効) |
|
|
123
|
+
| `OSV_MCP_PREFER_DOWNLOAD` | `1` または `true` 指定時、PATH上のosv-scannerを使わず、チェックサム検証済みの自動ダウンロードバイナリを常に使用します(PATH汚染による偽バイナリ実行の防止。`OSV_SCANNER_PATH` の明示指定は引き続き最優先) |
|
|
122
124
|
|
|
123
125
|
> **推奨**: `OSV_MCP_ALLOWED_ROOT` は未設定でも動作しますが、その場合は任意の絶対パスをスキャンできてしまいます。悪意ある指示(プロンプトインジェクション)経由で意図しないディレクトリをスキャンさせられる経路を塞ぐため、プロジェクト置き場のルート(例: `~/projects`)を設定しておくことを推奨します。各クライアントの設定で `"env": {"OSV_MCP_ALLOWED_ROOT": "/Users/you/projects"}` のように渡せます(Codex CLIのTOMLでは `[mcp_servers.osv-scanner.env]` セクション)。
|
|
124
126
|
|
|
127
|
+
> **本番運用の推奨構成**: 共有サーバーやCI等の運用環境では、次の3つをセットで設定してください。
|
|
128
|
+
> - `OSV_MCP_ALLOWED_ROOT=/スキャン対象のルート` — スキャン範囲の境界を固定
|
|
129
|
+
> - `OSV_MCP_REQUIRE_ALLOWED_ROOT=1` — 境界未設定なら起動を拒否(fail-closed)
|
|
130
|
+
> - `OSV_SCANNER_PATH=/管理者所有の絶対パス` または `OSV_MCP_PREFER_DOWNLOAD=1` — PATH解決に依存せず、実行するバイナリを固定
|
|
131
|
+
|
|
125
132
|
## 提供ツール
|
|
126
133
|
|
|
127
134
|
### `scan_java_project`
|
|
@@ -261,7 +268,7 @@ Java(Maven)プロジェクトをスキャンし、既知の脆弱性レポート
|
|
|
261
268
|
|
|
262
269
|
脆弱性診断ツール自体が攻撃経路にならないよう、以下を実装しています。
|
|
263
270
|
|
|
264
|
-
- **サプライチェーン対策**: バイナリの自動ダウンロードは公式GitHub Releasesに限定し、バージョンをピン留め。**パッケージに埋め込まれたSHA256チェックサム**で検証します(配布元のSHA256SUMSファイルは信用しないため、リリース側が改ざんされても検出可能)
|
|
271
|
+
- **サプライチェーン対策**: バイナリの自動ダウンロードは公式GitHub Releasesに限定し、バージョンをピン留め。**パッケージに埋め込まれたSHA256チェックサム**で検証します(配布元のSHA256SUMSファイルは信用しないため、リリース側が改ざんされても検出可能)。検証合格まで実行権限を与えず、キャッシュ済みバイナリも使用のたびに再検証します。`OSV_MCP_PREFER_DOWNLOAD=1` でPATH上の未検証バイナリを使わない運用も選べます
|
|
265
272
|
- **コマンドインジェクション対策**: シェルを経由しない `spawn` + 引数配列で実行。OSV-Scannerへの引数は固定リストのみで、可変部は検証済み絶対パス1つだけ
|
|
266
273
|
- **パストラバーサル対策**: 入力パスは `realpath` でシンボリックリンク解決後に境界チェック。pom.xml探索ではシンボリックリンクを辿りません
|
|
267
274
|
- **DoS対策**: タイムアウト・stdout上限・stderr抜粋上限を設定。スキャン結果は防御的にパースし、形式不正でも例外を投げません。同時実行スキャン数も上限(デフォルト2)を設け、並列リクエストによるプロセスの無制限起動を防ぎます
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* - OSV_MCP_ALLOWED_ROOT: 指定時、このディレクトリ配下以外のスキャンを拒否する(設定を推奨)
|
|
8
8
|
* - OSV_MCP_REQUIRE_ALLOWED_ROOT: 1/true指定時、OSV_MCP_ALLOWED_ROOT未設定なら起動を拒否する
|
|
9
9
|
* - OSV_MCP_MAX_CONCURRENT_SCANS: 同時実行スキャン数の上限(デフォルト2)
|
|
10
|
+
* - OSV_MCP_AUTO_DOWNLOAD: 0/false指定時、バイナリの自動ダウンロードを無効化
|
|
11
|
+
* - OSV_MCP_PREFER_DOWNLOAD: 1/true指定時、PATH上のバイナリを使わず検証済み自動ダウンロードを優先
|
|
10
12
|
*/
|
|
11
13
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12
14
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -30,7 +32,7 @@ if (startupWarning !== null) {
|
|
|
30
32
|
// NOTE: リリース時はpackage.jsonのversionと同じ値に更新すること
|
|
31
33
|
const server = new McpServer({
|
|
32
34
|
name: "osv-scanner-mcp",
|
|
33
|
-
version: "0.1.
|
|
35
|
+
version: "0.1.4",
|
|
34
36
|
});
|
|
35
37
|
server.registerTool("scan_java_project", {
|
|
36
38
|
title: "Javaプロジェクトの脆弱性スキャン",
|
|
@@ -52,23 +52,34 @@ export function installGuidance(env = process.env) {
|
|
|
52
52
|
].join("\n");
|
|
53
53
|
}
|
|
54
54
|
export const AUTO_DOWNLOAD_ENV = "OSV_MCP_AUTO_DOWNLOAD";
|
|
55
|
+
export const PREFER_DOWNLOAD_ENV = "OSV_MCP_PREFER_DOWNLOAD";
|
|
55
56
|
function isAutoDownloadEnabled(env) {
|
|
56
57
|
const value = env[AUTO_DOWNLOAD_ENV]?.trim().toLowerCase();
|
|
57
58
|
return value !== "0" && value !== "false";
|
|
58
59
|
}
|
|
60
|
+
function isPreferDownloadEnabled(env) {
|
|
61
|
+
const value = env[PREFER_DOWNLOAD_ENV]?.trim().toLowerCase();
|
|
62
|
+
return value === "1" || value === "true" || value === "yes";
|
|
63
|
+
}
|
|
59
64
|
/**
|
|
60
65
|
* バイナリのパスを解決する。
|
|
61
66
|
* 探索順: OSV_SCANNER_PATH(明示指定時はダウンロードにフォールバックしない)
|
|
62
67
|
* → PATH → 自動ダウンロード(チェックサム検証付き、OSV_MCP_AUTO_DOWNLOAD=0で無効化)。
|
|
68
|
+
* OSV_MCP_PREFER_DOWNLOAD=1 の場合はPATH探索をスキップし、チェックサム検証済みの
|
|
69
|
+
* 自動ダウンロードを優先する(PATH汚染による偽バイナリ実行の防止。明示指定は引き続き最優先)。
|
|
63
70
|
* どれも不可なら案内メッセージ付きのScanToolErrorを投げる。
|
|
64
71
|
*/
|
|
65
72
|
export async function resolveOsvScannerBinary(env = process.env, options = {}) {
|
|
66
|
-
const binary = await findOsvScannerBinary(env);
|
|
67
|
-
if (binary !== null) {
|
|
68
|
-
return binary;
|
|
69
|
-
}
|
|
70
73
|
const explicit = env[OSV_SCANNER_PATH_ENV];
|
|
71
74
|
const explicitlySpecified = explicit !== undefined && explicit.trim() !== "";
|
|
75
|
+
// PATH上のバイナリはチェックサム検証を経ていないため、運用ではスキップ可能にする
|
|
76
|
+
const skipPathLookup = !explicitlySpecified && isPreferDownloadEnabled(env);
|
|
77
|
+
if (!skipPathLookup) {
|
|
78
|
+
const binary = await findOsvScannerBinary(env);
|
|
79
|
+
if (binary !== null) {
|
|
80
|
+
return binary;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
72
83
|
// 明示指定が無効な場合は、意図しないバイナリの使用を避けるためダウンロードしない
|
|
73
84
|
if (!explicitlySpecified && isAutoDownloadEnabled(env)) {
|
|
74
85
|
const download = options.downloadFn ??
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "osv-scanner-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "MCP server that wraps Google's OSV-Scanner to scan Java projects for known vulnerabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^26.1.0",
|
|
46
46
|
"@vitest/coverage-v8": "^4.1.9",
|
|
47
|
-
"typescript": "^
|
|
47
|
+
"typescript": "^7.0.2",
|
|
48
48
|
"vitest": "^4.1.9"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|