Rustのzipクレートの脆弱性CVE-2026-115905、検査をすり抜けて別のファイルを上書きされるおそれ。9.0.5以降も既定で無効の検査を有効にする方法
CVE-2026-115905RustのZIPのクレートzipで、検査では無害なファイルに見えるZIPから、展開のときに別のファイルを上書きされるおそれがある脆弱性CVE-2026-115905が、2026年10月18日にzip-rsから公表されました。修正の9.0.5で入った食い違いの検査は、互換性のため既定で無効です。版を上げるだけでは展開の動きが変わらないため、この記事では、対象の構成の見分け方、検査を有効にする書き方、上げる先の版を説明します。
2026-11-01更新:一次情報(提供元のアドバイザリ・コミット・ソース、crates.io、RustSec、KEV)と照合し、検査を有効にする書き方、上げる先の9.1.0、検査の道具で見つからない点を加えて書き直しました。
- 対象はzip 9.0.4以下で、ZIPの中身を確かめる部品と展開する部品が、別の読み方(末尾の目録か、各ファイルの直前のヘッダーか)をしている構成です。
- 上げる先は9.1.0以上です(11月1日時点の最新は9.2.1)。9.0.5には、提供元が公表した別の2件が残っています。8系以前に修正版はありません。
- 更新したら
enforce_header_consistency(true)などで検査を有効にします。cargo auditが参照するRustSecのデータベースには、11月1日時点でこの件の記録がありません。
01zipクレートのCVE-2026-115905で起きること
ZIPファイルでは、各ファイルの名前が、本体の直前(ローカルファイルヘッダー)と末尾の目録(セントラルディレクトリ)の2か所に書かれます。提供元のアドバイザリによると、9.0.4以下のZipArchiveは目録の名前だけを使い、逐次読み込みのZipStreamReaderは本体の直前の名前だけを使って展開します。2か所の名前を食い違わせたZIPは、読む部品によって別のファイルに見えます。[1]
アドバイザリの例では、目録にdoc_report.pdf、本体の直前にcron_worker.shと書いたZIPが、目録で確かめる検査を通り、ZipStreamReaderでの展開で既存のスクリプトを上書きします。既存のファイルを書き換えられると、サービスの停止や、仕込まれたスクリプトによるコード実行につながるおそれがあります。[1]
深刻度は、提供元の評価でCVSS 4.0の10.0(緊急)です。NVDは11月1日時点で独自の評価をしておらず、提供元と同じ値を載せています。[1][3]
名前を2か所で食い違わせたZIPが、目録で確かめる検査を通り、展開で別のファイルを上書きする
提供元のアドバイザリの例を、受け取ったZIP・読む部品・起きることの順に並べる。
zipクレートの9.0.4以下
出典 zip-rs「GHSA-m665-v7pm-7grj」(2026-10-18)
02zipクレートの脆弱性の対象になる構成
提供元が影響を受けるとしているのは、目録を基準にする読み方を信じた処理と、本体の直前のヘッダーを基準にする読み方の処理が組み合わさる場合です。逆の組み合わせも含みます。[1]
| 構成の例 | 見方 |
|---|---|
受け取ったZIPをZipArchiveで名前や拡張子を確かめ、ZipStreamReaderで展開する | 提供元が示す典型の例 |
ウイルス検査やアップロードの検査(目録で判定する別の道具)を通したZIPを、ZipStreamReaderで展開する | 対象。検査の道具がRustでなくても同じ |
ZipStreamReaderで確かめ、別の道具やZipArchiveで展開する | 逆の組み合わせとして対象 |
確認と展開を同じZipArchiveだけで行い、他の道具に渡さない | アドバイザリが説明する組み合わせに当たらない(対象外とは書かれていない) |
提供元は、利用者が送ったZIPを自動で展開するサービスや、検査と展開を別の部品で行う構成を、影響を受ける例に挙げています。ZipStreamReaderはzip::unstable::streamにあるので、コードの中でこの名前を探すと見分けの手がかりになります。[1]
03悪用の状況
2026年11月1日時点で、米国のCISAが公開している「悪用が確認された脆弱性の一覧(KEV)」には載っていません。
今後30日以内に悪用される確率の推定値(EPSS)は0.3%です(2026-11-01時点)。見込みは高くない部類ですが、推定値で、悪用されないことを保証するものではありません。
提供元のアドバイザリには、検査をすり抜けて既存のスクリプトを上書きするまでを再現するテストのコード(PoC)と、その実行結果が載っています。当社はPoCを検証していません。[1]
公表と同じ日に9.0.5が出て、11月1日時点でKEVには載っていない
提供元の公表、データベースへの登録、悪用の状況の確認を日付の順に並べる(日本時間)。
提供元(zip-rs) データベース・公的機関
2026年10月18日
2026年10月27日
2026年10月27日
2026年10月29日
2026年11月1日
出典 zip-rs「GHSA-m665-v7pm-7grj」(2026-10-18)、NVD「CVE-2026-115905」(2026-10-27)、米CISA「Known Exploited Vulnerabilities Catalog」(2026-11-01確認)
04zipクレートの対象の版と推奨する版
GitHub Advisoryの記載は「9.0.4以下が対象、修正版は9.0.5」です。9.0.5は日本時間の10月18日に公開されました。8系以前に向けた修正版は、アドバイザリに記載がありません。[1][2][9]
| 系列 | 対象 | 今回の件が直る版 | 推奨する版 |
|---|---|---|---|
| 9系 | 9.0.4以下 | 9.0.5 | 9.1.0以上(最新は9.2.1) |
| 8系以前 | 対象(9.0.4以下に含まれる) | 記載なし(出典で確認) | 9系の9.1.0以上へ移る |
9.0.5で止めないのは、提供元が10月27日(日本時間)に公表した別の2件が残るためです。ZipArchive::newが前の目録に戻って読み、他の道具と違う中身に見える問題(GHSA-wjr6-mhvj-cjvm、2.1.4〜9.0.5)と、厳密な検査が末尾の欠けたZIPを通してしまう問題(GHSA-gmfj-vffv-32pw、9.1.0未満)で、どちらも9.1.0で直りました。9系に必要なRustは1.88以上で、8系と同じです。[7][8][9]
9.0.5で今回の件は直るが別の2件が残り、どの版でも食い違いの検査は既定で無効
版ごとに、今回の件、9.0.5に残る2件、食い違いの検査の扱いを並べる。
出典 zip-rs「GHSA-m665-v7pm-7grj」(2026-10-18)、同「GHSA-wjr6-mhvj-cjvm」「GHSA-gmfj-vffv-32pw」(2026-10-27)、同「v9.1.0」(2026-10-24)
05zipクレートを確かめて上げ、検査を有効にする手順
使っているzipの版と、どのクレートが使っているかを確かめます。複数の版が入っていると表示されたら、
cargo tree -i zip@8.6.0のように版を付けます。ターミナルcargo tree -i zipCargo.lockに記録された版も確かめます。ターミナルgrep -n -A1 'name = "zip"' Cargo.lockコードの中で、逐次読み込みの部品を使っている箇所を探します。
ターミナルgrep -rn -E 'ZipStreamReader|unstable::stream' --include='*.rs' .Cargo.tomlの指定を9.1.0以上が入る範囲にしてから更新します。8系以前からは大きな版の更新です。他のクレートが古い版を求めている場合は、そのクレートも更新します。ターミナル# Cargo.toml の [dependencies] を zip = "9.1" にしてから cargo update -p zip展開の処理で、食い違いの検査を有効にします(使っている部品の行だけを入れます)。
Rustuse zip::read::ExtractOptions; use zip::unstable::stream::ZipStreamReader; // 逐次読み込みで展開する場合 ZipStreamReader::new(reader).enforce_header_consistency(true).extract(&dir)?; // ZipArchiveで確かめて展開する場合(extract_with_optionsは9.1.0以降) archive.validate_header_consistency()?; archive.extract_with_options(&dir, ExtractOptions::default().enforce_header_consistency(true))?;テストを通したあと、もう一度版を確かめます。本番で動いている成果物(コンテナのイメージなど)も作り直します。
ターミナルcargo test cargo tree -i zip
06すぐに上げられないとき
07上げても既定では検査されない。有効にする書き方
9.0.5で入った修正は、本体の直前のヘッダーと目録の食い違いを見つける検査です。修正のコミットとソースには「互換性のため、ZipStreamReader::newはヘッダーの一致を確かめない」と書かれていて、11月1日時点の最新の9.2.1でも既定は無効のままです。版を上げただけでは、展開の動きは変わりません。[4][5]
検査を有効にする書き方は、使っている部品で次のように違います。[4][5][6]
| 使い方 | 有効にする書き方 | 使える版 |
|---|---|---|
ZipStreamReaderで展開する | ZipStreamReader::new(r).enforce_header_consistency(true) | 9.0.5以降 |
ZipArchiveの全体を確かめる | archive.validate_header_consistency() | 9.0.5以降 |
ZipArchiveから1件ずつ読む | ZipReadOptionsのenforce_header_consistency(true)をby_name_with_optionsに渡す | 9.0.5以降 |
ZipArchiveでまとめて展開する | ExtractOptions::default().enforce_header_consistency(true)をextract_with_optionsに渡す | 9.1.0以降 |
食い違いが見つかると、展開はZipError::InvalidArchiveで止まります。9.2.1のvalidate_header_consistency()は、目録に同じ名前が重複している場合も誤りを返します。[5]
08cargo auditやDependabotで見つからないことがある
cargo auditは、RustSecのデータベースでCargo.lockを調べます。11月1日時点で、RustSecにあるzipの記録は4件で、CVE-2026-115905は含まれていません。cargo auditで何も出なくても、対象外とは判断できません。[10]
この件はGitHub Advisory DatabaseとOSVに載っていますが、9.0.5に残る2件は提供元のリポジトリにだけ公表されていて、11月1日時点でGitHub Advisory Databaseに収録されていません。OSVで9.0.5を調べても何も出ないため、これらを使う道具では9.0.5で解決と表示されることがあります。Cargo.lockの版を、提供元のアドバイザリの一覧と照らし合わせます。[2][7][8][11]
脆弱性の公表・更新一覧で、Rustの関連情報を調べることもできます。

よくある質問
9.0.5に上げました。対応は済みましたか?
まだです。9.0.5の検査は既定で無効なので、enforce_header_consistency(true)などで有効にします。また9.0.5には別の2件が残るため、9.1.0以上に上げます。[4][5][7][8]
ZipArchiveだけで確認と展開をしています。対象ですか?
同じZipArchiveで確かめて展開し、他の道具に渡さないなら、アドバイザリが説明する組み合わせには当たりません。ただし、アップロードの段階で別の道具が中身を確かめている場合は、その道具との組み合わせになります。9.0.5に残るGHSA-wjr6-mhvj-cjvmはZipArchive::newの問題なので、9.1.0以上に上げる必要は変わりません。[1][7]
8系を使っています。8系の修正版を待てばよいですか?
アドバイザリに8系以前の修正版の記載はありません。crates.ioでは、8系は2026年4月の8.6.0が最後で、その後は9系だけが公開されています。9系へ移ります。[1][9]
自分のコードではzipを使っていません。
他のクレートの依存で入っていることがあります。cargo tree -i zipで、どのクレートがzipを使っているかを確かめます。そのクレートがZipStreamReaderを使っているか、検査を有効にしているかは、そのクレートのソースや告知で確かめます。
出典・参考資料
- zip-rs:GHSA-m665-v7pm-7grj(提供元のアドバイザリ)2026-10-18公表・10-27更新(日本時間) / 仕組み、対象(9.0.4以下)、修正版9.0.5、影響を受ける構成、PoC、CVSS 4.0 10.0
- GitHub Advisory Database:GHSA-m665-v7pm-7grj2026-10-29収録(日本時間) / 収録日、対象と修正版の記載
- NVD:CVE-2026-1159052026-10-27登録(日本時間) / 登録日、NVDが分析待ちで、提供元のCVSSを載せていること
- zip-rs:修正のコミット8068ab42026-10-16 / 検査が選んで有効にする方式(opt-in)で追加されたこと、ZipArchiveのvalidate_header_consistency、ZipReadOptionsの設定
- zip-rs:zip 9.2.1のソース(src/read/stream.rs・zip_archive.rs)2026-11-01確認 / 最新版でもZipStreamReader::newの既定が無効であること、InvalidArchiveで止まること、重複した名前の扱い
- zip-rs:v9.1.0のリリースノート(PR #1109)2026-10-24 / ExtractOptionsのenforce_header_consistencyの追加
- zip-rs:GHSA-wjr6-mhvj-cjvm2026-10-27(日本時間) / 2.1.4〜9.0.5が対象、9.1.0で修正
- zip-rs:GHSA-gmfj-vffv-32pw2026-10-27(日本時間) / 9.1.0未満が対象、9.1.0で修正
- crates.io:zipの版の一覧2026-11-01確認 / 9.0.5・9.1.0・9.2.1の公開日、8系の最後が8.6.0、必要なRustの版
- RustSec:advisory-db(zipの記録)2026-11-01確認 / cargo auditが参照するデータベース、zipの記録が4件でこの件が無いこと
- OSV:zip 9.0.5の照会2026-11-01確認 / 9.0.5で該当が出ないこと
- リリースノート:github.com/zip-rs/zip2/releases/tag/v9.0.5GitHub Advisoryの参考リンク / 修正の内容・経緯
あわせて読みたい記事
PHPのWindows版のBrotliの脆弱性、8.5.12-1などへの入れ替えとcURL・Guzzleの確かめ方(CVE-2026-111497)
PHPのWindows版に同梱のBrotliの脆弱性CVE-2026-111497は、米CISAが悪用を確認しています。10月21日の版も対象のままである理由、GuzzleやWordPressで自動展開が有効になる条件、8.5.12-1などへの入れ替えと確かめ方を説明します。
Brotliの脆弱性の確認方法、PythonとNode.jsで対象かを確かめて直す(CVE-2026-111497、コード実行のおそれ)
圧縮形式Brotliの展開処理の脆弱性CVE-2026-111497(HTTP2Shell)は、米CISAが悪用を確認しています。Pythonのbrotli・brotlicffi、Node.jsの同梱版などで、自分の版と構成が対象かを確かめる方法と修正版を、言語ごとに説明します。
Starletteの脆弱性BadHost、Hostヘッダーでパスによる認証の確認を回避されるおそれ。FastAPIを上げても古い版が残る場合の確かめ方
Starletteの脆弱性CVE-2026-48710(BadHost)は、細工したHostヘッダーでrequest.url.pathを偽り、パスで判定するアクセスの確認を回避されるおそれがあります。9月2日にKEVに追加されました。FastAPI・vLLM・LiteLLMの下で古いStarletteが残る例と、間接依存の確かめ方を説明します。