[解説] AxiosのNode.js環境におけるプロトタイプ汚染ソケットハイジャック脆弱性 (CVE-2026-101905)
はじめに:Node.jsを利用するフロントエンドエンジニアへ
皆さん、こんにちは!普段のウェブ開発でAxiosは欠かせないHTTPクライアントライブラリの一つですよね。特にNode.js環境でのBFF(Backend for Frontend)やSSR(Server-Side Rendering)では、サーバーサイドでのAPI呼び出しにAxiosを活用している方も多いでしょう。今回は、AxiosのNode.js HTTPアダプターに存在する、プロトタイプ汚染を悪用したソケットハイジャックの脆弱性(GHSA-m8m8-qj5v-23w3 / CVE-2026-101905)について解説します。この脆弱性は深刻度「high」と評価されており、Node.js環境でAxiosを使っている場合は注意が必要です。
脆弱性の概要:Axiosが引き起こすわけではない「プロトタイプ汚染」の悪用
この脆弱性は、Axios自体がプロトタイプ汚染(Prototype Pollution)を引き起こすものではありません。Axiosが動作しているNode.jsプロセス内で、**既に何らかの方法で `Object.prototype` が汚染されている状況**が前提となります。そのような状況下で、AxiosのNode HTTPアダプターが特定のNode.jsリクエストオプションを処理する際、「read-side gadget」として機能し、汚染されたプロパティを読み取ってしまうことで問題が発生します。
具体的には、Node.jsのHTTPクライアントがリクエストオプションを内部的にコピー・正規化する際に、欠落しているオプションが`Object.prototype`から継承されてしまう可能性があるというものです。その中でも、特に敏感なオプションである`createConnection`が汚染されている場合、攻撃者はAxiosが行うHTTPリクエストのソケット接続先を乗っ取ることができます。
なぜNode.js環境のみが影響を受けるのか?
この脆弱性は、Axiosの「Node.js HTTPアダプター」にのみ影響します。ブラウザ環境でAxiosを使用している場合は影響を受けません。これは、ブラウザとNode.jsでHTTPリクエストの実行メカニズムが異なるためです。ブラウザ環境では `XMLHttpRequest` や `fetch` API を利用しますが、Node.js環境ではNode.js標準の `http` / `https` モジュールを使用します。今回の問題は、このNode.js標準モジュールへのオプション渡し方に起因するため、ブラウザは影響範囲外となります。
具体的な影響と攻撃シナリオ
この脆弱性が悪用されると、以下のような深刻な影響が発生する可能性があります。
攻撃者は、標的となるアプリケーションのAxiosリクエストのソケット層を乗っ取り、本来の宛先とは異なる、攻撃者が制御するエンドポイントへリクエストをリダイレクトさせることができます。これにより、以下の事態が発生し得ます。
<ul><li><b>機密情報の窃取:</b> `Authorization` ヘッダー、クッキー、APIキー、サービス認証情報など、リクエストに含まれる機密情報を攻撃者サーバーが受け取ってしまいます。</li><li><b>レスポンスの操作:</b> 攻撃者はアプリケーションに対して、偽のレスポンスを返すことができます。これにより、アプリケーションの動作を不正に制御したり、ユーザーに誤った情報を提示したりすることが可能になります。</li><li><b>URL検証の回避:</b> 厄介な点として、Axiosを呼び出す前にURLの正当性を検証するようなSSRFP (Server-Side Request Forgery Protection) 対策を講じていても、この脆弱性はそれを迂回します。なぜなら、Axiosのコンフィグ上は正規のURLを指しているように見えても、実際のソケット接続先が攻撃者によって制御されるためです。</li></ul>
これにより、BFFやAPIサーバーとして動作するNode.jsアプリケーションが、意図せず内部システムへの認証情報を漏洩させたり、外部サービスからの情報を改ざんされたりするリスクがあります。
技術的な詳細:なぜ `Object.create(null)` を使ってもダメなのか?
Axiosの `lib/adapters/http.js` では、HTTPリクエストのオプションを構築する際に、通常プロトタイプ汚染対策として用いられる `Object.assign(Object.create(null), { ... })` という形式で、プロトタイプを持たないオブジェクトを作成しています。これにより、直接的なプロトタイプからの継承を防ぐことを意図しています。
しかし、問題はここから発生します。Node.jsのHTTPクライアントは、Axiosから受け取ったリクエストオプションを、接続作成前に通常のオブジェクトにコピーしたり、正規化したりする内部処理を行います。このコピー処理の後、オプションオブジェクトに特定のプロパティ(例: `createConnection`)が明示的に設定されていない場合、そのプロパティは `Object.prototype` から継承されてしまうのです。もし `Object.prototype.createConnection` がプロセス内で汚染されていた場合、Node.jsは汚染された関数を呼び出し、ソケット接続をハイジャックされてしまいます。
対策:どのように身を守るか
この脆弱性からシステムを守るためには、以下の対策を検討してください。
<ul><li><b>プロトタイプ汚染源の特定と排除:</b> まずは、アプリケーションの依存関係全体を見直し、`Object.prototype`を汚染するような脆弱なライブラリやコードが存在しないかを確認し、修正またはアップグレードすることが最も根本的な対策です。</li><li><b>Axiosのアップデート:</b> Axiosのパッチがリリースされた場合は、速やかに最新バージョンにアップデートしてください。報告によると、対策として `createConnection: undefined` をアダプターオプションに追加することで、この脆弱性を防ぐことができるとされています。</li><li><b>カスタムトランスポートやエージェントの利用:</b> 高リスクな内部クライアントに対しては、Axiosのカスタムトランスポートやカスタムエージェントを実装し、接続作成動作を明示的に制御・強制する方法も有効です。この中で、`createConnection: undefined` のように、Node.jsの敏感なHTTPオプションに安全なデフォルト値を設定することで、継承による悪用を防ぎます。</li><li><b>Node.jsの敏感なオプションへの注意:</b> `createConnection` だけでなく、`lookup`, `timeout`, `localAddress`, `servername`, `signal` など、接続やTLSに影響を与える可能性のあるNode.jsの他のHTTPオプションについても、継承による意図しない動作が発生しないよう注意を払うことが推奨されます。</li></ul>
まとめ
今回のAxiosの脆弱性は、Axios自体がプロトタイプ汚染を引き起こすわけではないものの、既に存在するプロトタイプ汚染を悪用することで、Node.js環境におけるHTTPリクエストのセキュリティを著しく侵害する可能性を秘めています。Node.jsでBFFやSSRを構築しているフロントエンドエンジニアの皆さんは、ご自身の環境がこの脆弱性の影響を受けないか、今一度確認し、適切な対策を講じるようにしてください。セキュリティは常に最新の情報をキャッチアップし、継続的に取り組むことが重要です。