CVE-2026-40175は、JavaScriptのHTTPクライアントaxiosで、別のライブラリが起こしたプロトタイプ汚染の値を送信ヘッダに取り込んでしまう脆弱性です。2026年4月10日の公開時はCVSS 10.0と発表され、「満点の脆弱性」として広く報じられました。ところが6日後、評価した当のGitHubが4.8(Moderate)へ差し替えています。
この記事では、NVDの登録情報とGitHub Advisory、axiosのリリースノートをもとに、深刻度が変わった経緯、影響版と修正版、Node.jsで攻撃がどこまで成立するかの実測結果、2026年3月のnpm不正版事件との違い、自分のプロジェクトの判定手順を整理します。版の情報は2026年10月2日時点です。
まとめ:深刻度は4.8へ下方修正済みでも1.20.0か0.34.0へ上げて終える
- CVSSは公開時10.0、2026年4月16日に4.8へ差し替え。NVDも4.8で確定しています。CISAの既知の悪用(KEV)には載っていません。
- 影響版は1.0.0以上1.15.0未満と、0.31.0未満。修正版は1.15.0と0.31.0です。0.x系にも修正版があります。
- ただし後続の勧告が多数出ており、2026年10月2日時点でまとめて直っている版は1.20.0と0.34.0です。
- 3月のnpm不正版(1.14.1・0.30.4)とは別の問題です。事件後に1.14.0や0.30.3へ戻したままのプロジェクトは、本CVEの影響版に残っています。
- 判定は
npm ls axiosと、lockfileに記録された実体の版で行います。版指定の行をgrepするだけの判定は誤ります。
CVE-2026-40175の仕組みと10.0から4.8へ下方修正された深刻度の経緯
GHSA-fvcv-3m26-pcqxが示したプロトタイプ汚染ガジェットの仕組み
GitHub Advisory(GHSA-fvcv-3m26-pcqx)によると、攻撃には前提があります。アプリの依存のどこか(qs、minimist、ini、body-parserなどが例示されています)に、Object.prototypeを書き換えられる別の脆弱性があることです。汚染が起きると、axiosは設定のマージ処理で汚染されたプロパティをヘッダとして拾い、CR/LF(改行)を除去しないまま送信しようとします。
axios自体は汚染の起点ではありません。すでに起きた汚染を外向きのリクエストへ運ぶ「ガジェット」として働く点が、この脆弱性の要点です。分類はCWE-113(ヘッダのCRLF)、CWE-444(リクエストスマグリング)、CWE-918(SSRF)の3つが付いています。
公開6日後にGitHubがCVSSを差し替えた評価の時系列と現在の値
評価の変化は、NVDの変更履歴とGitHub Advisoryで確認できます。
| 日付(UTC) | 主体 | 内容 |
|---|---|---|
| 2026-04-07 | axios | 修正を含む1.15.0を公開 |
| 2026-04-09 | axios | リポジトリで勧告を公開 |
| 2026-04-10 | GitHub・NVD | CVE公開。CVSS 3.1は10.0 |
| 2026-04-12 | axios | 0.x系の修正版0.31.0を公開 |
| 2026-04-16 | GitHub | CVSSを4.8に差し替え |
| 2026-04-21 | NVD | 初回分析で4.8 MEDIUMを付与 |
| 2026-05-12 | CISA | SSVC判定:悪用はPoC段階、自動化不可 |
公開時の10.0はAC:L・S:C・C/I/Aとも高という評価でした。4.8への差し替え後はAC:H・S:U・C:L・I:L・A:Nとなり、攻撃条件と影響範囲の評価が変わっています。GHSAの本文も「Moderate」「別のプロトタイプ汚染と到達可能な標的が必要な、複雑な攻撃チェーンの一部」に書き換えられています。Red Hatは自社製品の評価として8.1を付けており、評価主体によって値が違う点は押さえておきましょう。悪用予測のEPSSは2026年10月1日時点で1.3%(パーセンタイル69.5%)です(FIRST EPSSのAPIで取得)。
影響版と修正版を1.x系と0.x系に分けた2026年10月時点の早見表
| 系列 | 影響版 | 本CVEの修正版 | 2026年10月の推奨版 |
|---|---|---|---|
| 1.x | 1.0.0〜1.14.x | 1.15.0 | 1.20.0 |
| 0.x | 0.31.0未満 | 0.31.0 | 0.34.0 |
0.x系の修正は0.31.0のリリースノートに「v1のヘッダ強化をバックポート」と書かれています。NVDの説明文には「0.3.1」とありますが、影響範囲の欄は「0.31.0未満」で、0.31.0の誤記と読めます。推奨版を1.15.0より新しくしているのは、2026年4月24日以降にaxiosの勧告が44件追加され、9月16日公表の12件が1.20.0と0.34.0で直っているためです。
Node.js環境で攻撃が成立する範囲をローカル実測で確かめた結果
CRLF入りの汚染値はNode.jsのhttpモジュールが送信前に拒否する
GHSAのPoCは、汚染値に改行を仕込んで1本のリクエストを2本に分け、AWSのメタデータサービスへトークン要求を紛れ込ませる筋書きです。Node.js 24.18.0でaxios 1.14.0と0.30.3に同じ形の汚染値を流したところ、Node.jsがERR_INVALID_CHARで送信前に拒否し、リクエストは分割されませんでした。
Node.js標準のhttpを使う構成では、PoCどおりのスマグリングは成立しにくい。4.8への下方修正(攻撃条件の複雑さがHigh)とも整合します。ただしNode.js以外のランタイムや独自の通信実装での挙動は今回確かめていません。
汚染値のヘッダ混入は1.15.2まで残り1.16.0で止まった検証結果
改行を含まない汚染値なら話が変わります。Object.prototype.commonに置いたヘッダが送信されるかを版ごとに確かめた結果が次の表です。
| axiosの版 | CRLF入りヘッダ | 汚染ヘッダの混入 |
|---|---|---|
| 1.14.0・0.30.3 | Node.jsが拒否 | 混入する |
| 1.15.0 | axiosが例外 | 混入する |
| 1.15.1・1.15.2・0.31.0 | 改行を除去して送信 | 混入する |
| 1.16.0以降・0.33.0以降 | 改行を除去して送信 | 混入しない |
本CVEの修正(1.15.0)は改行の扱いを直したもので、汚染値を拾う動作そのものは残っていました。1.16.0ではマージ処理の読み取り側ガジェット(CVE-2026-44490)などが修正されており、この版から混入が止まります。1.15.0で対応を終えた組織も、推奨版まで上げる理由がここにあります。
EC2のIMDSv2強制とLambdaの認証情報の受け渡しで変わる被害範囲
想定される被害の中心は、サーバー内部から到達できるサービスへの不正な要求、いわゆるSSRFです。仕組みと防御はSSRFとは?クラウドメタデータ悪用と防御実装で詳しく扱っています。EC2では、トークン必須のIMDSv2へ切り替えると、単純なGETでの認証情報の読み出しを防げます。設定はAWS公式の手順のとおり--http-tokens requiredです。
Lambdaでは認証情報の受け渡し方が異なるため、防御の着眼点も別です。実行ロールの一時認証情報はIMDSではなく、環境変数のAWS_ACCESS_KEY_IDなどで渡されます。メタデータを狙う筋書きよりも、関数に付けたロールの権限を絞ることが効きます。
3月のnpmサプライチェーン攻撃との違いとロールバック先に潜む落とし穴
不正版1.14.1・0.30.4のマルウェア混入事件と本CVEは別の問題
2026年3月31日、メンテナーのアカウントが乗っ取られ、不正版の1.14.1と0.30.4がnpmで約3時間公開されました。axiosのポストモーテムによると、入口はリードメンテナーの端末を狙ったソーシャルエンジニアリングとRATで、不正版は03:15 UTCに削除されています。マルウェアを取り込む事件であり、コードの欠陥であるCVE-2026-40175とは原因も対処も違います。
感染の確認と端末の対処はaxiosにマルウェア混入(1.14.1・0.30.4)の感染確認と対処にまとめています。不正版を入れた端末は、版を上げるだけでは済みません。認証情報の総入れ替えが必要です。
事件後に1.14.0や0.30.3へ戻したプロジェクトが影響版に残る理由
事件の直後、ポストモーテムを含む多くの手順は「1.14.0(0.x系は0.30.3)へ戻す」と案内しました。この2つは不正版の直前の正規版ですが、本CVEの修正前でもあります。版を固定して事件を乗り切ったプロジェクトほど、影響版に留まりやすい構図です。
事件対応の完了報告が出ているプロジェクトでも、lockfileの版をもう一度確かめてください。次の章の判定スクリプトは、不正版と本CVEと後続の勧告を一度に判定できます。
lockfileとnpm auditで影響有無を判定する確認手順と判定スクリプト
npm lsで確認するtwilio・contentful経由のaxios間接依存
最初にnpm ls axiosで、依存ツリーの全経路を表示します。axiosは間接依存で入ることが多く、npm registryの最新版で確かめると、twilio 6.1.2は^1.13.5、contentful 11.12.10は^1.15.0でaxiosに依存しています。一方、Stripe・Firebase Admin・AWS SDK(v3)の最新版はaxiosに依存していません。
# 依存ツリー内のすべての axios と経路を表示する(npm)
npm ls axios
# pnpm と Yarn の場合
pnpm why axios
yarn why axios
手元で、localtunnel 2.0.2が入れ子で抱えるaxios 0.21.4がnpm lsに表示されることを確かめました。直接依存を1.20.0へ上げても、入れ子の古い版は残ります。
package-lock.jsonの実体の版を読む判定スクリプトとgrep判定の落とし穴
lockfileの"axios": "^1.13.5"のような行は依存の版指定で、実際に入っている版ではありません。実体の版は"node_modules/axios"の項目のversionにあります。次のスクリプトは実体の版だけを読み、3段階で判定します。
// package-lock.json(lockfileVersion 2/3)から axios の実体の版をすべて拾って判定する
// 使い方: node check-axios.js [package-lock.json のパス]
const fs = require('fs');
const file = process.argv[2] || 'package-lock.json';
const lock = JSON.parse(fs.readFileSync(file, 'utf8'));
if (!lock.packages) {
console.error('lockfileVersion 1 は読めません。npm 7 以降で lockfile を作り直してください');
process.exit(2);
}
// a が b より古ければ true(x.y.z の数値比較)
function older(a, b) {
const x = a.split('.').map(Number), y = b.split('.').map(Number);
for (let i = 0; i !== 3; i++) { if (x[i] !== y[i]) return Math.sign(x[i] - y[i]) === -1; }
return false;
}
let worst = 0;
for (const [path, meta] of Object.entries(lock.packages)) {
if (!(path === 'node_modules/axios' || path.endsWith('/node_modules/axios')) || !meta.version) continue;
const v = meta.version.split('-')[0];
const zero = v.startsWith('0.');
let lv = 0, msg = 'OK(2026-10-02時点で公表済みの勧告はすべて修正済み)';
if (v === '1.14.1' || v === '0.30.4') { lv = 3; msg = '不正版(マルウェア混入)。端末を侵害済みとして扱う'; }
else if (older(v, zero ? '0.31.0' : '1.15.0')) { lv = 2; msg = 'CVE-2026-40175 の影響あり'; }
else if (older(v, zero ? '0.34.0' : '1.20.0')) { lv = 1; msg = 'CVE-2026-40175 は修正済み。後続の勧告が未修正'; }
worst = Math.max(worst, lv);
console.log(meta.version.padEnd(8) + ' ' + path + ' ' + msg);
}
process.exit(worst);
Node.js 24.18.0で、1.14.0、1.15.2、1.20.0、0.33.0、入れ子の0.21.4、不正版1.14.1の6構成を判定し、表示と終了コード(0〜3)が想定どおりになることを確かめました。終了コードが0以外ならCIを止める、という使い方ができます。pnpmとYarnのlockfileは形式が違うため、このスクリプトでは読めません。
npm auditの終了コードをCIの失敗条件にするaudit-levelの設定
npm auditはGitHub Advisory Databaseを参照し、本CVE(GHSA-fvcv-3m26-pcqx)も検出します。--audit-levelで指定した重大度以上が見つかると終了コード1を返します。
# 本番依存だけを対象に、high 以上があれば終了コード 1 を返す
npm audit --omit=dev --audit-level=high
1.14.0の構成では終了コード1、1.20.0の構成では0になることを確かめています。本CVEは単体ではmoderateのため、--audit-level=highだけで運用すると本CVEのみの環境は通ってしまいます。判定スクリプトと併用するか、moderateまで止めるかを決めておきましょう。依存更新を自動化するならDependabotの設定とRenovateとの違い、検査の全体像はSCA(ソフトウェア構成分析)とはが参考になります。
1.20.0や0.34.0へ更新する手順と1.15系で変わったヘッダ検証の挙動
直接依存の更新とoverridesで間接依存のaxiosをそろえる手順
# 直接依存を 2026-10-02 時点の latest へ
npm install [email protected]
# 0.x 系を使い続ける場合
npm install [email protected]
間接依存の古い版は、親パッケージの更新を待つか、package.jsonのoverridesで上書きします。
{
"overrides": {
"axios": "1.20.0"
}
}
上の設定を入れてnpm installし直すと、localtunnelの入れ子にあった0.21.4も1.20.0にそろい、判定スクリプトの終了コードが0になりました。0.xから1.xへの上書きはメジャー更新にあたるため、親パッケージの通信処理を必ずテストしてください。版の確認方法や基本の使い方はaxiosの最新版1.20の確認方法と使い方にあります。
1.15.0の例外から1.15.1の除去へ変わったヘッダ検証と更新時のテスト観点
修正PR #10660で入った1.15.0の検証は、CR/LFを含むヘッダを例外で拒否します。この変更でMDNのリポジトリが失敗したとPRのコメントで報告され、メンテナーも互換性を壊す変更だったと認めています。1.15.1では「例外を投げずに値を整える」動作へ改められました(2026年4月19日公開)。手元でも、1.15.0は例外、1.15.1以降は改行を除去して送信しています。
1.15.0を飛ばして1.20.0へ上げる場合、改行入りのヘッダはエラーにならず黙って整形されます。外部の値(環境変数やDB)をヘッダに入れている箇所は、送信される値が変わっていないかをテストで確かめると安心です。
対応の優先度を決めるプロトタイプ汚染の入口と実行環境の判断基準
至急扱いにする条件と通常の依存更新の周期で足りる条件の線引き
深刻度4.8は「放置してよい」という意味ではありません。後続の勧告にはhigh評価のものが多く、1.20.0未満を使い続けると、それらもまとめて抱えることになります。そのうえで、優先度は次の条件で決めると判断がぶれません。表の先頭行は、サーバー側でaxiosを使う構成が対象です。
| 条件 | 扱い |
|---|---|
| axios使用・qs等で外部入力を深くマージ | 至急。1.20.0へ更新 |
| EC2でIMDSv1が有効なまま | 至急。IMDSv2強制も同時に実施 |
| 不正版事件後1.14.0・0.30.3に固定 | 至急。固定を外して更新 |
| ブラウザだけで使い、サーバー側の実行経路が無い | 通常の更新周期で可 |
| devDependenciesのみ・外部入力なし | 通常の更新周期で可 |
ブラウザ専用でも、Next.jsなどでサーバー側の処理に同じaxiosを使っていれば「サーバー側あり」として扱います。逆に、深刻度の数字が下がったことだけを理由に更新を先送りする判断は勧めません。依存の棚卸しと更新の体制づくりから相談したい場合は、脆弱性診断・セキュリティ診断で、依存ライブラリの点検を含めてお手伝いしています。
よくある質問
CVE-2026-40175について、検索の多い質問に答えます。
CVE-2026-40175のCVSSは10.0と4.8のどちらが正しいですか?
2026年10月2日時点の公式値は4.8(Moderate)です。公開時にGitHubが付けた10.0は、2026年4月16日に4.8へ差し替えられ、NVDも4月21日に4.8を付けています。古い記事やスキャナの結果に10.0が残っていることがあるため、NVDかGitHub Advisoryの現在値で確かめてください。
影響を受けるaxiosのバージョンはどれですか?
1.0.0以上1.15.0未満と、0.31.0未満です。修正版は1.15.0と0.31.0ですが、その後に勧告が多数出ているため、2026年10月2日時点では1.20.0(0.x系は0.34.0)への更新を勧めます。版はnpm ls axiosかlockfileの実体の版で確かめます。
0.x系のまま使い続けても大丈夫ですか?
0.x系にも修正版があり、2026年10月2日時点の最新は0.34.0です。本CVEのためだけに1.xへ移る必要はありません。ただし本CVEでは1.x系の修正(4月7日)から0.31.0(4月12日)まで5日の差がありました。0.x系を使う場合は、勧告が出るたびに0.x側の修正版の有無を確かめる運用が要ります。
ブラウザだけで使っている場合も対応が必要ですか?
ブラウザはCR/LFを含むヘッダを送らないため、改行を使う筋書きは成立しにくいです。ただし汚染値がヘッダに混入する動作は1.16.0未満に残っていました。SSRやAPIルートでサーバー側からも同じaxiosを使っていないかを確かめ、通常の更新周期で1.20.0へ上げてください。
CVE-2026-40175は実際に悪用されていますか?
2026年10月1日版のCISA KEV(既知の悪用カタログ)には掲載されていません。CISAのSSVC判定は「PoCあり・自動化不可」です。GitHub AdvisoryにPoCが載っているため、悪用されていないことを理由に更新を遅らせず、1.20.0へ上げることを勧めます。
関連記事
- axiosにマルウェア混入(1.14.1・0.30.4)|感染確認・対処と再発防止の設定:3月の不正版事件の確認と対処
- Axios(アクシオス)とは?最新版1.20の確認方法・インストール・使い方:版の確認と更新の基本
- SSRFとは?仕組み・クラウドメタデータ悪用と防御実装を解説:メタデータを狙う攻撃と防御
- Dependabotとは|dependabot.ymlの設定・料金・Renovateとの違い:依存更新の自動化
- SCAとは?ソフトウェア構成分析の仕組みとSAST・SBOMとの違い:依存の脆弱性検査の全体像