2026年5月14日、Webサーバシェア世界約34%を占めるNGINXにCVSS 9.2(Critical)のヒープバッファオーバーフロー脆弱性が公表された。CVE-2026-42945、通称「NGINX Rift」は2008年頃に導入されたngx_http_rewrite_moduleのバグに起因し、18年間にわたってコードベースに潜伏し続けた。3日後の5月17日にはPoC由来のアクティブ攻撃が実環境で確認されており、未パッチのNGINX運用者には即時対応が求められる。

セキュリティ脆弱性の体系的な防御アプローチについてはサプライチェーンセキュリティ完全ガイド2026|攻撃手法・防御ツール・実践チェックリストをご覧ください。

3行でわかるCVE-2026-42945
  • 影響範囲: NGINX 0.6.27〜1.30.0 / Plus R32〜R36・Ingress Controller・App Protect WAFに影響。修正版は1.30.1 / 1.31.0
  • 攻撃内容: ngx_http_rewrite_moduleの2パス処理バグでヒープを溢れさせ、認証不要でDoS/RCEを実行。5月17日からPoC由来の攻撃進行中。
  • 即効緩和: 設定ファイルの無名キャプチャ($1)をnamed capture(${name})に書き換え + nginx -s reloadで再起動なしに緩和可能。

NGINX Riftとは:CVE-2026-42945の全体像

NGINX Riftはセキュリティ研究チーム「depthfirst」が2026年4月18日に自律スキャニングにより発見し、4月21日にF5/NGINXへ責任ある開示(responsible disclosure)を行った脆弱性だ。公表から5月13〜14日のパッチリリースまでわずか23日という異例の速さで対応が進んだ一方、翌17日にはPoC(概念実証コード)が公開されアクティブ攻撃が確認された。

NGINXは世界の約34%のWebサーバで稼働しており、この影響範囲はApacheやCaddy、Iisの比ではない。さらにNGINXは多くのKubernetesクラスタのIngress Controllerとして、またF5のApp Protect WAFのエンジンとして組み込まれているため、一台のNGINXバイナリを修正するだけでなく、複数の製品スタックを個別に更新する必要がある。

CVSSスコアはv4.0で9.2(Critical)、v3.1では8.1(High)と評価されている。v4.0とv3.1でスコアが異なるのは、RCEの実現可能性に関する評価の違いによるもの(後述)。

根本原因:ngx_http_rewrite_moduleの2パス処理バグ

NGINX Riftの技術的本質はngx_http_script.c内の状態フラグ汚染だ。NGINXのrewriteエンジンはリクエスト処理を2つのフェーズで行う。

  1. 計算フェーズ(length pass): 置換後URLのバッファサイズを計算してメモリを確保
  2. コピーフェーズ(copy pass): 実際のURLデータをバッファに書き込む

問題が起きるのは、rewriteディレクティブの置換文字列に?(クエリ文字列区切り)が含まれる場合だ。この時ngx_http_script_start_args_code関数がe->is_args = 1フラグを立てる。このフラグは計算フェーズでは正しくリセットされるが、コピーフェーズではそのまま引き継がれてしまう

結果としてngx_escape_uri関数は計算フェーズで算出したバッファサイズよりも大きなデータを書き込もうとし、ヒープバッファオーバーフローが発生する。さらに致命的なのは、オーバーフローで書き込まれるバイト列が攻撃者の送ったURIから直接導出される点だ。これは「攻撃者がメモリ破壊の内容を制御できる」ことを意味し、単純なサービス妨害を超えたコード実行への道を開く。

この条件が揃うのは以下の3つが同時に成立する場合だ:

  • 無名PCREキャプチャ$1$2など)を含むrewriteルール
  • 置換文字列に?を含む(クエリ文字列を付加する形式)
  • 同じlocation/server内で別のrewrite・if・setディレクティブが後続する

これはAPIゲートウェイやリバースプロキシ設定で頻繁に見られるパターンであり、多数の本番環境が潜在的に影響を受けている。

攻撃手法の詳細:ヒープfeng shuiによるRCE

DoS(ワーカープロセスのクラッシュと再起動)は「trivial and reliable(自明かつ安定的)」とAlmaLinuxのアセスメントで評価されており、特別な技術なしに実現できる。一方、完全なRCEは6ステップのヒープfeng shuiテクニックを用いる高度な攻撃だ。

RCE攻撃の6ステップ(Picus Security解析より)
  • Step 1 — 接続確立: HTTPリクエストのヘッダを途中で送り、NGINXワーカーにリクエストプールを確保させる
  • Step 2 — 被害コネクション配置: 別のコネクションで隣接するメモリプール構造体を確保させる(ヒープ隣接配置)
  • Step 3 — オーバーフロートリガー: Step 1のヘッダを完成させてリクエストを完了させ、被害プールのcleanupハンドラポインタを上書きする
  • Step 4 — ヒープスプレー: POSTボディで予測可能なメモリ位置に偽のcleanup構造体(関数ポインタ付き)を配置する
  • Step 5 — アドレス総当たり: URIセーフなバイト列のみで構成されるアドレスを総当たりで探す
  • Step 6 — プール解放: プールのcleanupフェーズで書き換えられたハンドラが実行され、任意コード実行を達成

重要な注記がある。公開されているPoCはRCEの実証にASLR(Address Space Layout Randomization)の無効化を必要とした。現代のLinuxディストリビューションではASLRがデフォルトで有効になっており、通常構成のサーバではRCEの難易度は大幅に上がる。ただしコンテナ環境や組み込み機器ではASLRが無効または弱化されているケースがある点に注意が必要だ。実際、Kubernetes上でのPodはホストのASLR設定に依存する。

タイムライン:18年の潜伏から3日間のアクティブ攻撃へ

timeline title NGINX Rift CVE-2026-42945 タイムライン 2008年頃 : ngx_http_rewrite_module
バグ導入 (NGINX 0.6.27) 2026-04-18 : depthfirstが自律スキャニングで発見 2026-04-21 : F5/NGINXへ責任ある開示 2026-05-13 : NGINX 1.30.1 / 1.31.0
パッチリリース 2026-05-14 : CVE公開・PoCコード公開 2026-05-17 : アクティブ攻撃確認
VulnCheck Canariesが検出 2026-05-20 : 世界規模での攻撃継続中

特筆すべきは発見から公開までの速さだ。通常のCVEサイクルは90日程度だが、今回は23日で対応が完了した。これはF5/NGINXの迅速な対応と、depthfirstによる責任ある開示の成功例と言える。ただしPoCの即日公開がアクティブ攻撃を加速させた点は議論の余地がある。

また、18年間このバグが発見されなかった背景として、脆弱性を引き起こす条件(無名キャプチャ + ? + 後続ディレクティブ)が比較的ニッチなパターンであり、かつ通常の動作テストでは問題が顕在化しにくいことが挙げられる。depthfirstが自律スキャニングツールによって発見できたのは、人間のセキュリティ研究者が見落としやすいこのようなコーナーケースを系統的に探索できたからだ。

影響範囲:製品別バージョン対応表

製品影響を受けるバージョン修正版優先度
NGINX Open Source(stable)0.6.27 〜 1.30.01.30.1緊急
NGINX Open Source(mainline)0.6.27 〜 1.30.01.31.0緊急
NGINX PlusR32 〜 R36R32 P6 / R36 P4緊急
NGINX Instance Manager2.16.0 〜 2.21.12.21.2以降
NGINX App Protect WAF4.9.0 〜 5.8.05.9.0以降緊急
NGINX Gateway Fabric1.3.0 〜 2.5.12.5.2以降
NGINX Ingress Controller3.5.0 〜 5.4.15.4.2以降緊急
F5 WAF for NGINX5.9.0 〜 5.12.15.12.2以降
特に注意すべき環境
  • Kubernetes Ingress Controller: クラスタ内の全トラフィックを処理するため、侵害された場合の影響が最大級
  • NGINX App Protect WAF: WAF自体が脆弱というアイロニー。WAFをバイパスしつつRCEを狙える
  • APIゲートウェイ: rewrite + set の組み合わせが多用されており、脆弱パターンの密度が高い
  • コンテナ環境(ASLRが弱化): DoSに留まらず本格的なRCEリスクが増大

脆弱な設定の特定:自分の環境を確認する方法

まず稼働中のNGINXバージョンを確認する。

# バージョン確認(パッチ済みか確認)
nginx -v
# またはサービス経由
systemctl status nginx | grep -i version

# 脆弱パターンの検出(無名キャプチャ + ? の組み合わせ)
grep -rn 'rewrite.*\$[0-9].*?' /etc/nginx/ 2>/dev/null
grep -rn 'rewrite.*\?.*\$[0-9]' /etc/nginx/ 2>/dev/null

# Kubernetes Ingress Controller のバージョン確認
kubectl get pods -n ingress-nginx -o jsonpath='{.items[*].spec.containers[*].image}'

脆弱なパターンの例は以下のようなものだ。

# ===== 脆弱な設定例 =====
# 条件: 無名キャプチャ($1) + ?(クエリ区切り)+ 後続ディレクティブ
server {
    location /api/ {
        # 危険: $1(無名キャプチャ)+ ? + 後続のsetディレクティブ
        rewrite ^/api/(.*)$ /v2/$1?format=json break;
        set $upstream http://backend;
        proxy_pass $upstream;
    }

    location /user/ {
        # 危険: 2つのrewriteの連鎖 + 無名キャプチャ + ?
        rewrite ^/user/([0-9]+)$ /profile?id=$1 last;
        rewrite ^/profile(.*)$ /api/profile$1 break;
    }
}

対策手順:named captureへの書き換えとパッチ適用

最優先の対策はパッチ(バージョンアップ)だ。ただし本番環境でのNGINXの即時再起動が困難な場合や、複数の製品スタックを段階的に更新する場合の暫定措置として、設定変更による緩和が有効だ。

# ===== 修正後の設定例:named captureへの書き換え =====
server {
    location /api/ {
        # 修正前: rewrite ^/api/(.*)$ /v2/$1?format=json break;
        # 修正後: 無名キャプチャ $1 を named capture ${path} に置換
        rewrite ^/api/(?P<path>.*)$ /v2/${path}?format=json break;
        set $upstream http://backend;
        proxy_pass $upstream;
    }

    location /user/ {
        # 修正前: rewrite ^/user/([0-9]+)$ /profile?id=$1 last;
        # 修正後: named capture ${uid} を使用
        rewrite ^/user/(?P<uid>[0-9]+)$ /profile?id=${uid} last;
        rewrite ^/profile(.*)$ /api/profile$1 break;
    }
}

# 変更後の適用(サービス停止なし)
# nginx -t && nginx -s reload

書き換えのルールはシンプルだ。(.*) のような無名キャプチャを (?P<name>.*) 形式の名前付きキャプチャに変え、参照箇所の$1${name}に置き換えるだけだ。設定変更後は必ずnginx -tで構文チェックを行い、nginx -s reloadでリロードすることでサービス停止なしに緩和が適用される。

Kubernetes環境の場合はIngressリソースのannotationも確認が必要だ。

# Kubernetes Ingress annotation での named capture 使用例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    # 修正前(脆弱)
    # nginx.ingress.kubernetes.io/rewrite-target: /v2/$1?format=json
    # 修正後(named capture)
    nginx.ingress.kubernetes.io/rewrite-target: /v2/${path}?format=json
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
    - http:
        paths:
          # 修正前: path: /api/(.*)
          # 修正後: named capture を使用
          - path: /api/(?P<path>.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: api-service
                port:
                  number: 8080

パッチ適用手順:各環境向けアップグレード

NGINX Open Sourceのアップグレード

# Ubuntu/Debian: 公式NGINXリポジトリ使用
apt-get update
apt-get install --only-upgrade nginx

# CentOS/RHEL/AlmaLinux
yum update nginx
# または dnf を使用する場合
dnf update nginx

# バージョン確認(1.30.1以上であることを確認)
nginx -v

# 設定テスト → リロード(ダウンタイムなし)
nginx -t && nginx -s reload

# AlmaLinuxの場合(アドバイザリ al-2026-056 対応)
# https://almalinux.org/blog/2026-05-13-nginx-rift-cve-2026-42945/ を参照

NGINX Plus のアップグレード

NGINX PlusユーザはF5公式アドバイザリ K000161019 を参照し、R32 P6またはR36 P4以上へのアップグレードを実施する。NGINXカスタマーポータルから更新パッケージを取得できる。

Kubernetes Ingress Controllerのアップグレード

# Helm を使用している場合
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --version 5.4.2  # 修正済み最小バージョン

# 更新後の確認
kubectl get pods -n ingress-nginx
kubectl describe pod -n ingress-nginx | grep -i image

CVE-2026-42945が示す「長期潜伏バグ」の危険性

NGINX Riftは18年間にわたって発見されなかったが、これは特異な事例ではない。近年の重大な脆弱性を振り返ると、XZ Utils backdoor(2024年)、OpenSSH regreSSHion(2024年)、Log4Shell(2021年)など、長年にわたって活用されてきたコアコンポーネントに潜む脆弱性が相次いで発見されている。

問題は「なぜ見つからなかったか」ではなく「なぜ今見つかったか」だ。depthfirstは自律スキャニングツールを使用して発見したと述べている。これはAIや自動化ツールがセキュリティ研究に本格的に組み込まれ始め、人間の目では見落としがちなコーナーケースを系統的に探索できるようになったことを示唆する。裏を返せば、攻撃者側も同様のツールを使って未知のゼロデイを掘り起こす時代に入ったということだ。

今回同時に発見された脆弱性は CVE-2026-42945 だけではない。depthfirstの開示によれば同じコードレビューサイクルで3つの追加CVE(CVSS 6.3〜8.3)も発見されており、NGINXのリライト処理全体に構造的な脆弱性が潜在していた可能性がある。

攻撃を受けた場合の検知・インシデント対応

NGINXのエラーログで以下のパターンはworkerクラッシュ(DoS試行の可能性)を示す。

# エラーログでworkerクラッシュを確認
grep -i "worker process.*exited\|segfault\|signal 11" /var/log/nginx/error.log

# アクセスログで異常なURIパターンを探す
# 長大なキャプチャグループを含むリクエスト
awk '{print $7}' /var/log/nginx/access.log | grep -E '%[0-9a-f]{2}.*%[0-9a-f]{2}' | sort | uniq -c | sort -rn | head -20

# 短時間に同一IPから大量リクエスト(DoSプローブ)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

アクティブ攻撃が確認された場合は:

  1. 即時:WAF/ロードバランサでリクエストブロック(後述のIPや特徴的なURIパターン)
  2. 短期:named captureへの書き換え + nginx -s reload で緩和(ダウンタイムなし)
  3. 計画:メンテナンスウィンドウで正式パッチ(1.30.1/1.31.0)へアップグレード
  4. 事後:ログを保全してインシデント分析を実施

開発・運用チームへのチェックリスト

CVE-2026-42945 即時対応チェックリスト
  • バージョン確認: nginx -v で 1.30.1 / 1.31.0 以上か確認
  • 脆弱設定スキャン: grep -rn 'rewrite.*\$[0-9].*?' /etc/nginx/ で無名キャプチャ+?を特定
  • named captureへの書き換え: $1${name} に変更し nginx -t && nginx -s reload
  • Kubernetes確認: Ingress Controllerのバージョン・annotationのキャプチャ形式を確認
  • NGINX Plus: F5カスタマーポータルからR32 P6 / R36 P4を取得して更新
  • 関連製品: App Protect WAF / Gateway Fabric / Instance Managerも個別更新
  • ログ監視: workerプロセスクラッシュログ / 異常URIパターンのアラート設定
  • ASLR確認: cat /proc/sys/kernel/randomize_va_space が 2 であることを確認(RCEリスク軽減)

NGINX Rift は2026年のWebインフラを直撃した高深刻度脆弱性の一つだ。同月に公表されたNext.js CVE-2026-44578のSSRF(Next.js CVE-2026-44578:WebSocket SSRF(CVSS 8.6)の仕組みと自己ホスト向け緊急対策)、GitHub Actions経由のサプライチェーン攻撃(GitHub Actions pull_request_targetの危険な設定ミスとサプライチェーン攻撃リスク)と並び、2026年5月はWebインフラのセキュリティが集中して試された月として記録されるだろう。根本的な対策は「パッチを当てる」という一点に尽きる。named captureへの書き換えはあくまで暫定措置であり、次のメンテナンスウィンドウでの正式アップグレードを必ず計画に入れてほしい。

参照ソース