Skip to content

fix(deps): update picomatch to version 4.0.7 - #347

Open
shinagawa-web wants to merge 1 commit into
mainfrom
fix/picomatch-redos-cve-2026-33671
Open

shinagawa-web wants to merge 1 commit into
mainfrom
fix/picomatch-redos-cve-2026-33671

Conversation

@shinagawa-web

@shinagawa-web shinagawa-web commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

概要

  • picomatch を全経路で脆弱性修正済みバージョンに更新(npm update picomatch
  • package-lock.json のみの変更、package.json は無変更

対象アラート

変更内容

依存元 変更前 変更後
eslint-plugin-strict-dependenciesmicromatch 2.3.1 2.3.2
npm-run-all2 4.0.4 4.0.7
tsuptinyglobby 4.0.4 4.0.7
vitest / vite 4.0.5 4.0.7
examples/vite, examples/vite-react-openapi 4.0.5 4.0.7

いずれも devDependencies 経由の間接依存(scope: runtime 表記だが実行時コードには到達しない)。

Reachability Assessment

本リポジトリでは picomatch を直接利用しておらず、ビルドツール(vite/vitest/tsup/eslint等)の内部依存としてのみ使用。ユーザー入力由来のglobパターンを渡す箇所は存在しないため、実際の悪用可能性は低い。念のため既存の推奨バージョンに追従。

@shinagawa-web shinagawa-web changed the title fix(deps): update picomatch to version 4.0.7 to address security vuln… fix(deps): update picomatch to version 4.0.7 Sep 17, 2026
@shinagawa-web

Copy link
Copy Markdown
Collaborator Author

picomatch 更新 PR レビュー

1. ライブラリの概要

picomatch は「Blazing fast and accurate glob matcher」を謳う、依存ゼロの glob→正規表現コンパイラ。braces / extglob / POSIX bracket / 正規表現拡張までサポートする、chokidar・vite・vitest・micromatch などが内部で使うマッチングエンジン。

2. バージョン情報

このPRはコード上の直接依存ではなく package-lock.json のみ を変更しています(package.json に picomatch の記載なし)。

系列 PR前 PR後 リリース日(npm)
2.x 2.3.1 2.3.2 2.3.1: 2022-01-02 / 2.3.2: 2026-03-23
4.x (複数箇所で 4.0.4/4.0.5混在) 4.0.4 / 4.0.5 4.0.7 4.0.4: 2026-03-23 / 4.0.5: 2026-07-02 / 4.0.6・4.0.7: 2026-08-24

npm registry (npm view picomatch versions) を確認した限り、picomatch の最新版は 4.0.7 であり、これを超えるmajor更新(5.x等)は存在しません。パッケージ名変更や organization 移管もありません。

3. 変更スコープの確認

package-lock.json 内の picomatch エントリ6箇所すべてが対象:

  • node_modules/picomatch (2.3.1→2.3.2)
  • node_modules/npm-run-all2/node_modules/picomatch (4.0.4→4.0.7)
  • node_modules/tinyglobby/node_modules/picomatch (4.0.4→4.0.7)
  • node_modules/vitest/node_modules/picomatch (4.0.5→4.0.7)
  • examples/vite/node_modules/picomatch (4.0.5→4.0.7)
  • examples/vite-react-openapi/node_modules/picomatch (4.0.5→4.0.7)

注記: node_modules/rollup-plugin-visualizer/node_modules/picomatch はこのPRの対象外ですが、確認したところPR適用前から既に 4.0.7(パッチ済み)でした。矛盾なし。

4. ライブラリの依存関係

picomatch はいずれも他パッケージの推移的依存として存在し、直接の親は以下の通り:

  • 2.x系: anymatch, micromatch, readdirp(いずれも chokidar 系ファイル監視スタック)
  • 4.x系: npm-run-all2, tinyglobby, vitest, vite, rollup-plugin-visualizer

依存されている側で、picomatch自体には依存パッケージなし(no dependencies を謳う通り)。

5. ライブラリの使用箇所とバージョン情報

git grep picomatch(lockfile除く)はリポジトリ全体で 0件package.json・CI設定・Dockerfile等、バージョン指定箇所も含めて picomatch への直接参照は見つかりませんでした。アプリケーションコードからの import/require も存在しません。すべてビルド/テストツール内部でのみ使用されています。

6. 変更内容の要約

今回のバージョン間で修正された既知脆弱性は2件(PR概要欄の「security vulnerabilities」という記述と一致、2026-03-23公開):

  • CVE-2026-33671 / GHSA-c2c7-rcm5-vvqj (High, CWE-1333 ReDoS): +(a|aa) のような繰り返しextglob量指定子がネストすると、破局的バックトラッキングを起こす正規表現が生成される。悪意あるglobパターンを受け取るアプリでDoSの恐れ。影響: <2.3.2, 3.0.0-3.0.1, 4.0.0-4.0.3。修正: 2.3.2/3.0.2/4.0.4
  • CVE-2026-33672 / GHSA-3v7f-55p6-f55p (Moderate, CWE-1321 プロトタイプ汚染由来のメソッドインジェクション): POSIX_REGEX_SOURCE オブジェクトが Object.prototype を継承していたため、[[:constructor:]] のようなパターンで継承メンバーが暗黙に文字列化され生成正規表現に混入、意図しないマッチが発生しうる。修正: 該当オブジェクトを __proto__: null 化。影響/修正バージョンはCVE-2026-33671と同一。

4.0.4以降さらに以下の修正が入っています(機能修正、CVEとは別):

  • 4.0.5: 「risky な繰り返しextglobの書き換え時に全分岐を保持する」「windowsオプションがbasenameマッチ時にも効くようにする」
  • 4.0.6: 「tokens要求時にフルパターンをスキャンする」「scanから完全なpattern partsを返す」
  • 4.0.7: 「括弧で囲まれた終端globstarのハンドリング」

特に4.0.5の「risky extglobの書き換えで全分岐を保持」は、4.0.4のReDoS修正が一部の正当なマッチを取りこぼす副作用(正しさの後退)を起こしていた可能性を示唆しており、4.0.4だけに留めず4.0.7まで上げた今回のPRの判断は妥当です。

7. コード・設定の更新

7-1. APIや仕様変更に伴うコード修正

API シグネチャの変更はありません(picomatch(pattern, options) の呼び出し形は不変)。修正は内部の正規表現コンパイルロジックのみです。

7-2. バージョン整合性の確認

picomatch を参照する全 requires レンジ(^2.0.4^4.0.5, ^3 || ^4 等、リポジトリ内で確認した全12箇所)は、更新後の 2.3.2 / 4.0.7 でいずれも充足されており、古い脆弱バージョンに解決される semver レンジの取りこぼしはありません。


追加観点: ランタイム default 挙動の変化

今回は major version 更新ではなく、feature flag のデフォルト反転のようなものはありません。ただし「同一入力に対する出力が暗黙に変わる」という点で、CVE修正自体が2つの実質的な default 挙動変化にあたるため、明示的に検証しました。

1. default挙動が変わった箇所の列挙

# 変化 旧挙動 新挙動
DC-1 POSIX bracket class の prototype 参照 (CVE-2026-33672) [[:constructor:]] 等、Object.prototype のメンバー名をbracket class名として書くと、その関数が暗黙に文字列化されて正規表現に混入し、意図しないマッチングを起こしていた POSIX_REGEX_SOURCE__proto__: null 化され、該当パターンは未定義値扱いとなり混入しない(マッチ結果が変わる)
DC-2 繰り返しextglob量指定子の書き換え (CVE-2026-33671 + 4.0.5でのリグレッション修正) `+(a aa)` 等のネストしたextglobが破局的バックトラッキングする正規表現にコンパイルされていた(および4.0.4時点の中間修正では一部の分岐を落として不一致になるケースがあった)

2. 旧defaultに依存するコードパターンの定義(grep可能な形)

  • DC-1: picomatch/micromatch/minimatch/anymatch 系のAPIに渡すglobパターン文字列内に、POSIXブラケットクラス構文 [[:xxx:]] があり、かつ xxxObject.prototype のメンバー名(constructor, toString, valueOf, hasOwnProperty, __proto__, isPrototypeOf 等)と一致する箇所。
    • 検索キーワード: \[\[:(constructor|toString|valueOf|hasOwnProperty|isPrototypeOf|propertyIsEnumerable|__proto__|__defineGetter__)\b
  • DC-2: 同APIに渡すglobパターン文字列内に、extglob量指定子構文 +(...), *(...), @(...), !(...), ?(...) が単体または入れ子で使われている箇所(特にalternation | を含む/ネストしているものがリスク高)。
    • 検索キーワード: [+*@!?]\([^)]*\) (設定ファイル・スクリプト・テストコード内のglob文字列が対象)

3. 上記パターンでの実際のgrep結果

git grep -nE '\[\[:' -- . ':!package-lock.json'      → 0件
git grep -nE '[+*@!?]\(' -- '*.json' '*.js' '*.ts' '*.tsx' '*.mjs' '*.cjs' '*.yml' '*.yaml'
  → 1件ヒット (pkgs/typed-api-spec/src/core/validator/validate.ts:120)
    `if (!(path in endpoints)) {` — これはTypeScriptの否定演算子であり、extglobパターンではない誤検出

判定: 実質0件。この2つの旧default依存パターンに該当する箇所はコードベース内に存在しません。

4. 「flag未設定=暗黙に旧defaultに依存」箇所の網羅チェック(非対称チェック回避)

react-router #9194 の教訓(明示的にflagを設定していた箇所だけ検証し、未設定で暗黙に旧defaultへ依存していた箇所を見逃した)を踏まえ、以下も確認しました:

  • picomatch を利用する設定サーフェス(vite.config.*, vitest.config.*, .gitignore風の include/exclude/watch.ignored/testMatch 等)を全ワークスペースで確認 → examples/vite, examples/vite-react-openapi, pkgs/typed-api-spec の設定ファイルはいずれも extglob/POSIXブラケットのどちらも使用しておらず、単純なデフォルト設定のまま。
  • npm-run-all2 の呼び出し (examples/misc/package.json: "test": "run-p test:*") はpicomatch 4.xで解釈される唯一の「明示的globパターン」だが、単純な * ワイルドカードでextglob/POSIXブラケットではないため、両CVE修正の影響範囲外。
  • ユーザー入力由来のglobパターンをpicomatch/micromatch/chokidar系APIに渡している箇所(DoS攻撃面になり得る箇所)はリポジトリ全体で0件 — picomatchは全てビルド/テストツール内部の静的globのみに使われている。

結論として、「flag未設定で暗黙に旧defaultへ依存」というケースに該当する箇所は見つかりませんでした。


8. 興味深い更新

特筆すべき新機能はなし。今回はセキュリティパッチ+内部正しさ修正が中心です。

9. 過去の失敗の調査

本リポジトリで picomatch に関連する過去のPR/issueのclose・revert事例は見つかりませんでした。

セクション間整合性チェック

  • セクション5の参照箇所リスト(0件)とセクション7-2の整合性確認対象は一致(他に整合すべき明示的バージョン記載箇所がないため)。
  • セクション3で列挙した6箇所の変更はいずれもセクション6のCVE修正で説明可能(未説明の変更なし)。
  • セクション4の依存関係(推移的devDependencyのみ)とセクション6の内容(アプリ非公開のビルドツール内部利用)に矛盾なし。

総合評価

LGTM(承認推奨)CVE-2026-33671(High, ReDoS)と CVE-2026-33672(Moderate, プロトタイプ汚染由来の誤マッチ)を修正するセキュリティパッチであり、直接依存ではなく開発ツールの推移的依存のみ、かつアプリケーションコードは影響を受ける構文(extglob量指定子・POSIXブラケットクラス)を一切使用していないため、マージによる回帰リスクは極めて低いと判断します。


🤖 Generated with Claude Code

@shinagawa-web shinagawa-web added the security Security vulnerability fix label Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Security vulnerability fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant