新たに公表されたNGINXのStreamモジュールにおける重大な認証前ヒープバッファオーバーフロー脆弱性、CVE-2026-42533として追跡されているこの問題は、未認証のリモート攻撃者がワーカープロセスをクラッシュさせ、任意コード実行を達成できる可能性があります。
この脆弱性のCVSS v4.0スコアは9.2で、バージョン0.9.6から1.31.2までのほぼすべてのNGINX Open Sourceに加え、37.0.3.1およびR36 P7より前のNGINX Plusビルドが影響を受けます。
この欠陥はngx_stream_script.c(940行目)のngx_stream_script_copy_capture_code関数に存在します。この関数は、Streamモジュールにおける複合値評価の際に正規表現キャプチャのコピー処理を担っています。
NGINXのssl_prereadモジュールは、TLSハンドシェイクのメタデータ(Server Name Indication、SNIを含む)をTLS終端処理の前に内部変数として抽出するため、これらの値はreturnのようなストリームレベルのディレクティブで利用できます。
このような値が「複合値」として処理される際、スクリプトエンジンは2パスのアルゴリズムを実行します。まず必要なバッファ長を計算し、その後実際のデータコピーを行うという流れです。
この脆弱性は、この2つのパスの間に(mapブロックで定義されたものなど)正規表現ベースの変数を評価すると、グローバルなPCREキャプチャ状態が変化してしまうことに起因します。
NGINXのスクリプトエンジンにおけるこの種の「2パス間のタイミング不整合」は、繰り返し現れる根本原因パターンであることが判明しています。HTTP rewriteモジュールのスクリプトエンジンにおける類似のロジック欠陥も、「Nginx Rift」と名付けられたCVE-2026-42945として個別に特定されています。
このケースでは、長さ計算のパスとコピーのパスがエンジンの状態変化によって食い違い、同様のヒープ破損が発生していました。
ssl_preread onが設定され、かつ$ssl_preread_server_nameに対する正規表現mapとキャプチャグループおよびマップされた変数の両方を参照するreturnディレクティブを組み合わせた構成を持つストリームリスナーに攻撃者が接続すると、このバグを引き起こすことができます。
サイズの大きいSNIフィールドを持つ細工されたTLS ClientHelloを送信することで、攻撃者はミスマッチを引き起こします。エンジンは長さ計算パスで短いバッファを算出しますが、コピーパスが実行される前にキャプチャ状態が更新されてしまうため、確保された領域よりも多くのデータが書き込まれてしまうのです。
この処理はssl_prereadの最中に完全に行われるため、TLSハンドシェイクの完了や認証チェックが行われる前に破損が発生します。これにより、インターネットに公開されたTCP/UDPプロキシは特に危険にさらされることになります。
Markakd氏は、AddressSanitizerで計装されstream_ssl_preread_moduleを有効化したNGINXビルドを用いてこの脆弱性を検証しました。PythonベースのPoCは、map $ssl_preread_server_name $m { ~^(.*)$ ok; }とreturn "$1$m"を設定したサーバーに対して、1,000バイトのSNIホスト名を含むTLS ClientHelloを送信しました。
このテストにより、サイズ1000バイトのヒープバッファオーバーフロー(WRITE)が確認されました。これはngx_palloc_block経由で確保された256バイトのヒープ領域からちょうど1バイト分はみ出す形で発生しており、クラッシュは940行目のngx_stream_script_copy_capture_code内のmemcpy呼び出しに直接起因することが突き止められています。
stream {}ブロック内でpreread変数に対して正規表現ベースのmapを使用している管理者は、設定内容を監査し、該当リスナーの露出を制限するとともに、スクリプトエンジンのキャプチャ状態処理に対処するNGINX側の今後のパッチ提供状況を注視すべきです。HTTPモジュールにおける同様の2パスオーバーフロー修正の前例を踏まえれば、なおさらその重要性が増します。
SOC調査の死角を減らし、ANY.RUNで脅威を早期に封じ込めることで、対応コストと業務への影響を削減しましょう。
翻訳元: https://cyberpress.org/nginx-heap-overflow-flaw/